Exemplo n.º 1
0
        private void CipherDescriptionTest()
        {
            CipherDescription cd1 = new CipherDescription(
                SymmetricEngines.RHX,
                192, IVSizes.V128,
                CipherModes.CTR,
                PaddingModes.None,
                BlockSizes.B128,
                RoundCounts.R22);

            byte[]            bcd = cd1.ToBytes();
            CipherDescription cd2 = new CipherDescription(bcd);

            if (!cd1.Equals(cd2))
            {
                throw new Exception("KeyFactoryTest: CipherDescription serialization has failed!");
            }
            MemoryStream      mcd = cd2.ToStream();
            CipherDescription cd3 = new CipherDescription(mcd);

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

            int x = cd1.GetHashCode();

            if (x != cd2.GetHashCode() || x != cd3.GetHashCode())
            {
                throw new Exception("KeyFactoryTest: CipherDescription hash code test has failed!");
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Build the PackageInfo structure from a <see cref="PackageKey"/> file
        /// </summary>
        ///
        /// <param name="Package">Populated PackageKey structure</param>
        public PackageInfo(PackageKey Package)
        {
            Description = Package.Description;
            Created     = new DateTime(Package.CreatedOn);
            Origin      = new Guid(Package.Authority.OriginId);
            string ptg = System.Text.Encoding.ASCII.GetString(Package.Authority.PackageTag);

            Tag         = ptg.Replace("\0", String.Empty);
            SubKeyCount = Package.SubKeyCount;
            Policies    = new List <KeyPolicies>();

            foreach (var flag in Enum.GetValues(typeof(KeyPolicies)))
            {
                if ((Package.Authority.KeyPolicy & (long)flag) == (long)flag)
                {
                    Policies.Add((KeyPolicies)flag);
                }
            }

            if (Package.Authority.OptionFlag == 0)
            {
                Expiration = DateTime.MaxValue;
            }
            else
            {
                Expiration = new DateTime(Package.Authority.OptionFlag);
            }
        }
Exemplo n.º 3
0
        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!");
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// CipherKey structure constructor.
        /// <para>KeyID and ExtRandom values must each be 16 bytes in length.
        /// If they are not specified they will be populated automatically.</para>
        /// </summary>
        ///
        /// <param name="Description">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.CipherDescription">CipherDescription</see> structure containing a complete description of the cipher instance</param>
        /// <param name="KeyId">The unique 16 byte ID field used to identify this key. A null value auto generates this field</param>
        /// <param name="ExtensionKey">An array of random bytes used to encrypt a message file extension. A null value auto generates this field</param>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if either the KeyId or ExtensionKey fields are null or invalid</exception>
        public CipherKey(CipherDescription Description, byte[] KeyId = null, byte[] ExtensionKey = null)
        {
            this.Description = Description;

            if (KeyId == null)
            {
                this.KeyId = Guid.NewGuid().ToByteArray();
            }
            else if (KeyId.Length != KEYUID_SIZE)
            {
                throw new CryptoProcessingException("CipherKey:CTor", "The KeyId must be exactly 16 bytes!", new ArgumentOutOfRangeException());
            }
            else
            {
                this.KeyId = KeyId;
            }

            if (ExtensionKey == null)
            {
                using (KeyGenerator gen = new KeyGenerator())
                    this.ExtensionKey = gen.GetBytes(16);
            }
            else if (ExtensionKey.Length != EXTKEY_SIZE)
            {
                throw new CryptoProcessingException("CipherKey:CTor", "The random extension field must be exactly 16 bytes!", new ArgumentOutOfRangeException());
            }
            else
            {
                this.ExtensionKey = ExtensionKey;
            }
        }
Exemplo n.º 5
0
        private void DescriptionTest(CipherDescription Description)
        {
            AllocateRandom(ref _iv, 16);
            AllocateRandom(ref _key, 32);
            AllocateRandom(ref _plnText);

            KeyParams    kp   = new KeyParams(_key, _iv);
            MemoryStream mIn  = new MemoryStream(_plnText);
            MemoryStream mOut = new MemoryStream();
            MemoryStream mRes = new MemoryStream();

            CipherStream cs = new CipherStream(Description);

            cs.Initialize(true, kp);
            cs.Write(mIn, mOut);

            mOut.Seek(0, SeekOrigin.Begin);

            cs.Initialize(false, kp);
            cs.Write(mOut, mRes);

            if (!Evaluate.AreEqual(mRes.ToArray(), _plnText))
            {
                throw new Exception("CipherStreamTest: Encrypted arrays are not equal!");
            }
        }
Exemplo n.º 6
0
        /// <remarks>
        /// Returns the populated KeyParams class
        /// </remarks>
        private KeyParams GetKeySet(MemoryStream InputStream, CipherDescription Description, long Position)
        {
            InputStream.Seek(Position, SeekOrigin.Begin);

            byte[] key = null;
            byte[] iv  = null;
            byte[] ikm = null;
            byte[] ext = new byte[EXTKEY_SIZE];

            if (Description.KeySize > 0)
            {
                key = new byte[Description.KeySize];
                InputStream.Read(key, 0, key.Length);
            }
            if (Description.IvSize > 0)
            {
                iv = new byte[Description.IvSize];
                InputStream.Read(iv, 0, iv.Length);
            }
            if (Description.MacKeySize > 0)
            {
                ikm = new byte[Description.MacKeySize];
                InputStream.Read(ikm, 0, ikm.Length);
            }

            InputStream.Read(ext, 0, ext.Length);

            return(new KeyParams(key, iv, ikm, ext));
        }
Exemplo n.º 7
0
        void SerializeStructTest()
        {
            CipherDescription cd = new CipherDescription(
                SymmetricEngines.RHX,
                192,
                IVSizes.V128,
                CipherModes.CTR,
                PaddingModes.PKCS7,
                BlockSizes.B128,
                RoundCounts.R22,
                Digests.Skein512,
                64,
                Digests.SHA512);

            CipherDescription cy = new CipherDescription(cd.ToStream());

            if (!cy.Equals(cd))
            {
                throw new Exception("CipherStreamTest: CipherDescriptions are not equal!");
            }

            cy.KeySize = 0;
            if (cy.Equals(cd))
            {
                throw new Exception("CipherStreamTest: CipherDescriptionsare not equal!");
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Initialize the CipherKey structure using a Stream
        /// </summary>
        ///
        /// <param name="KeyStream">The Stream containing the CipherKey</param>
        public CipherKey(Stream KeyStream)
        {
            BinaryReader reader = new BinaryReader(KeyStream);

            Description  = new CipherDescription(reader.ReadBytes(CipherDescription.GetHeaderSize()));
            KeyId        = reader.ReadBytes(KEYUID_SIZE);
            ExtensionKey = reader.ReadBytes(EXTKEY_SIZE);
        }
Exemplo n.º 9
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);
        }
Exemplo n.º 10
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);
        }
Exemplo n.º 11
0
        private void PackageKeyTest()
        {
            CipherDescription cd1 = new CipherDescription(
                SymmetricEngines.RHX,
                192, IVSizes.V128,
                CipherModes.CTR,
                PaddingModes.None,
                BlockSizes.B128,
                RoundCounts.R22);

            CSPPrng rnd = new CSPPrng();

            byte[] di = new byte[16];
            byte[] oi = new byte[16];
            byte[] pi = new byte[16];
            byte[] pd = new byte[32];
            byte[] ti = new byte[16];
            rnd.GetBytes(di);
            rnd.GetBytes(oi);
            rnd.GetBytes(pi);
            rnd.GetBytes(pd);
            rnd.GetBytes(ti);
            KeyAuthority ka1 = new KeyAuthority(di, oi, pi, pd, KeyPolicies.IdentityRestrict | KeyPolicies.NoExport | KeyPolicies.NoNarrative, 1, ti);

            MemoryStream mk  = new MemoryStream();
            PackageKey   pk1 = new PackageKey(ka1, cd1, 100);

            PackageFactory pf = new PackageFactory(mk, ka1);

            pf.Create(pk1);

            byte[]     bpk = pk1.ToBytes();
            PackageKey pk2 = new PackageKey(bpk);

            if (!pk1.Equals(pk2))
            {
                throw new Exception("KeyFactoryTest: PackageKey serialization has failed!");
            }

            PackageKey pk3 = new PackageKey(mk);

            if (!pk1.Equals(pk3))
            {
                throw new Exception("KeyFactoryTest: PackageKey serialization has failed!");
            }
            if (pk1.GetHashCode() != pk2.GetHashCode() || pk1.GetHashCode() != pk3.GetHashCode())
            {
                throw new Exception("KeyFactoryTest: PackageKey hash code test has failed!");
            }
            pf.Dispose();
        }
Exemplo n.º 12
0
        /// <summary>
        /// Extract a KeyParams and CipherKey
        /// </summary>
        ///
        /// <param name="KeyHeader">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Processing.Structure.CipherKey"/> that receives the cipher description, key id, and extension key</param>
        /// <param name="KeyParam">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.KeyParams"/> container that receives the key material from the file</param>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if the key file could not be found or a Header parameter does not match the keystream length</exception>
        public void Extract(out CipherKey KeyHeader, out KeyParams KeyParam)
        {
            m_keyStream.Seek(0, SeekOrigin.Begin);
            KeyHeader = new CipherKey(m_keyStream);
            CipherDescription dsc = KeyHeader.Description;

            if (m_keyStream.Length < dsc.KeySize + dsc.IvSize + dsc.MacKeySize + CipherKey.GetHeaderSize())
            {
                throw new CryptoProcessingException("KeyFactory:Extract", "The size of the key file does not align with the CipherKey sizes! Key is corrupt.", new ArgumentOutOfRangeException());
            }

            m_keyStream.Seek(CipherKey.GetHeaderSize(), SeekOrigin.Begin);
            KeyParam = KeyParams.DeSerialize(m_keyStream);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Initialize an empty VolumeKey structure
        /// </summary>
        ///
        /// <param name="Tag">The volume tag; a 32 byte field identifying this volume</param>
        /// <param name="Description">The cipher description</param>
        /// <param name="Count">The number of key/vector pairs</param>
        public VolumeKey(byte[] Tag, CipherDescription Description, int Count)
        {
            this.Tag = new byte[TAG_SIZE];
            Array.Copy(Tag, this.Tag, Math.Min(Tag.Length, TAG_SIZE));
            this.Description = Description;
            this.Count       = Count;
            this.FileId      = new int[Count];
            this.State       = new byte[Count];
            int id = new CSPPrng().Next();

            for (int i = 0; i < Count; ++i)
            {
                this.State[i]  = (byte)VolumeKeyStates.Unassigned;
                this.FileId[i] = id + i;
            }
        }
Exemplo n.º 14
0
        /// <summary>
        /// Initialize the VolumeKey structure using a Stream
        /// </summary>
        ///
        /// <param name="KeyStream">The Stream containing the VolumeKey</param>
        public VolumeKey(Stream KeyStream)
        {
            KeyStream.Seek(0, SeekOrigin.Begin);
            BinaryReader reader = new BinaryReader(KeyStream);

            Tag         = reader.ReadBytes(TAG_SIZE);
            Description = new CipherDescription(KeyStream);
            Count       = reader.ReadInt32();
            FileId      = new int[Count];

            for (int i = 0; i < Count; i++)
            {
                FileId[i] = reader.ReadInt32();
            }

            State = reader.ReadBytes(Count);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Create a volume key file using a manual description of the cipher parameters.
        /// </summary>
        ///
        /// <param name="KeyCount">The number of key sets associated with this volume key</param>
        /// <param name="EngineType">The Cryptographic <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.SymmetricEngines">Engine</see> type</param>
        /// <param name="KeySize">The cipher Key Size in bytes</param>
        /// <param name="IvSize">Size of the cipher <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.IVSizes">Initialization Vector</see></param>
        /// <param name="CipherType">The type of <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.CipherModes">Cipher Mode</see></param>
        /// <param name="PaddingType">The type of cipher <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.PaddingModes">Padding Mode</see></param>
        /// <param name="BlockSize">The cipher <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.BlockSizes">Block Size</see></param>
        /// <param name="Rounds">The number of diffusion <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.RoundCounts">Rounds</see></param>
        /// <param name="KdfEngine">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.Digests">Digest</see> engine used to power the key schedule Key Derivation Function in HX and M series ciphers</param>
        ///
        /// <returns>A populated VolumeKey</returns>
        public MemoryStream CreateKey(int KeyCount, SymmetricEngines EngineType, int KeySize, IVSizes IvSize,
                                      CipherModes CipherType, PaddingModes PaddingType, BlockSizes BlockSize, RoundCounts Rounds, Digests KdfEngine)
        {
            CipherDescription dsc = new CipherDescription()
            {
                EngineType  = (int)EngineType,
                KeySize     = KeySize,
                IvSize      = (int)IvSize,
                CipherType  = (int)CipherType,
                PaddingType = (int)PaddingType,
                BlockSize   = (int)BlockSize,
                RoundCount  = (int)Rounds,
                KdfEngine   = (int)KdfEngine,
            };

            return(CreateKey(dsc, KeyCount));
        }
Exemplo n.º 16
0
        /// <summary>
        /// Extract the next valid subkey set (Expired flag not set) as a KeyParam, and a CipherDescription structure.
        /// <para>Used only when calling a Encryption function.</para>
        /// </summary>
        ///
        /// <param name="Description">out: The CipherDescription structure; the properties required to create a specific cipher instance</param>
        /// <param name="KeyParam">out: The KeyParams class containing a unique key, initialization vector and HMAC key</param>
        ///
        /// <returns>The KeyId array used to identify a subkey set; set as the KeyId in a MessageHeader structure</returns>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if the user has insufficient access rights to perform encryption with this key.</exception>
        public byte[] NextKey(out CipherDescription Description, out KeyParams KeyParam)
        {
            if (!AccessScope.Equals(KeyScope.Creator))
            {
                throw new CryptoProcessingException("PackageFactory:NextKey", "You do not have permission to encrypt with this key!", new UnauthorizedAccessException());
            }

            try
            {
                // get the key data
                MemoryStream keyStream = GetKeyStream();
                // get the next unused key for encryption
                int index = PackageKey.NextSubkey(keyStream);

                if (index == -1)
                {
                    throw new CryptoProcessingException("PackageFactory:NextKey", "The key file has expired! There are no keys left available for encryption.", new Exception());
                }

                // get the cipher description
                Description = m_keyPackage.Description;
                // store the subkey identity, this is written into the message header to identify the subkey
                byte[] keyId = m_keyPackage.SubKeyID[index];
                // get the starting position of the keying material within the package
                long keyPos = PackageKey.SubKeyOffset(keyStream, keyId);

                // no unused keys in the package file
                if (keyPos == -1)
                {
                    throw new CryptoProcessingException("PackageFactory:NextKey", "The key file has expired! There are no keys left available for encryption.", new Exception());
                }

                // get the keying material
                KeyParam = GetKeySet(keyStream, m_keyPackage.Description, keyPos);
                // mark the subkey as expired
                PackageKey.SubKeySetPolicy(keyStream, index, (long)PackageKeyStates.Expired);
                // write to file
                WriteKeyStream(keyStream);
                // return the subkey id
                return(keyId);
            }
            catch
            {
                throw;
            }
        }
Exemplo n.º 17
0
        /// <summary>
        /// A PackageKey header structure.
        /// </summary>
        ///
        /// <param name="Authority">The <see cref="KeyAuthority">KeyAuthority</see> structure containing the key authorization schema.</param>
        /// <param name="Cipher">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.CipherDescription">CipherDescription</see> structure containing a complete description of the cipher instance.</param>
        /// <param name="SubKeyCount">The number of Key Sets contained in this key package file.</param>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if an invalid ExtensionKey is used</exception>
        public PackageKey(KeyAuthority Authority, CipherDescription Cipher, int SubKeyCount)
        {
            this.KeyPolicy   = Authority.KeyPolicy;
            this.Authority   = Authority;
            this.Description = Cipher;
            this.SubKeyCount = SubKeyCount;
            SubKeyPolicy     = new long[SubKeyCount];
            SubKeyID         = new byte[SubKeyCount][];

            // generate the subkey ids and set master policy
            for (int i = 0; i < SubKeyCount; i++)
            {
                SubKeyPolicy[i] = (long)Authority.KeyPolicy;
                SubKeyID[i]     = Guid.NewGuid().ToByteArray();
            }

            CreatedOn = DateTime.Now.Ticks;
        }
Exemplo n.º 18
0
        /// <summary>
        /// Gdet the starting position of the key material (key/iv/mac key) of a specific subkey within the key package file
        /// </summary>
        ///
        /// <param name="KeyStream">The stream containing a key package</param>
        /// <param name="KeyId">The unique identifies of the sub key</param>
        ///
        /// <returns>The starting position index of the key material</returns>
        public static long SubKeyOffset(Stream KeyStream, byte[] KeyId)
        {
            long keyPos = -1;
            int  index  = IndexFromId(KeyStream, KeyId);

            if (index == -1)
            {
                return(keyPos);
            }

            int keyCount             = GetSubKeyCount(KeyStream);
            CipherDescription cipher = GetCipherDescription(KeyStream);
            int keySize = cipher.KeySize + cipher.IvSize + cipher.MacKeySize;
            int hdrSize = POLICY_SIZE + CREATE_SIZE + KEYAUT_SIZE + DESC_SIZE + KEYCNT_SIZE + (keyCount * (KEYPOL_SIZE + KEYID_SIZE));

            keyPos = hdrSize + (keySize * index);

            return(keyPos);
        }
Exemplo n.º 19
0
        /// <summary>
        /// Create a single use Key file using a manual description of the cipher parameters.
        /// </summary>
        ///
        /// <param name="KeyParam">An initialized and populated key material container</param>
        /// <param name="EngineType">The Cryptographic <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.SymmetricEngines">Engine</see> type</param>
        /// <param name="KeySize">The cipher Key Size in bytes</param>
        /// <param name="IvSize">Size of the cipher <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.IVSizes">Initialization Vector</see></param>
        /// <param name="CipherType">The type of <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.CipherModes">Cipher Mode</see></param>
        /// <param name="PaddingType">The type of cipher <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.PaddingModes">Padding Mode</see></param>
        /// <param name="BlockSize">The cipher <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.BlockSizes">Block Size</see></param>
        /// <param name="Rounds">The number of diffusion <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.RoundCounts">Rounds</see></param>
        /// <param name="KdfEngine">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.Digests">Digest</see> engine used to power the key schedule Key Derivation Function in HX and M series ciphers</param>
        /// <param name="MacSize">The size of the HMAC message authentication code; a zeroed parameter means authentication is not enabled with this key</param>
        /// <param name="MacEngine">The HMAC <see cref="VTDev.Libraries.CEXEngine.Crypto.Enumeration.Digests">Digest</see> engine used to authenticate a message file encrypted with this key</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(KeyParams KeyParam, SymmetricEngines EngineType, int KeySize, IVSizes IvSize, CipherModes CipherType,
                           PaddingModes PaddingType, BlockSizes BlockSize, RoundCounts Rounds, Digests KdfEngine, int MacSize, Digests MacEngine)
        {
            CipherDescription dsc = new CipherDescription()
            {
                EngineType  = (int)EngineType,
                KeySize     = KeySize,
                IvSize      = (int)IvSize,
                CipherType  = (int)CipherType,
                PaddingType = (int)PaddingType,
                BlockSize   = (int)BlockSize,
                RoundCount  = (int)Rounds,
                KdfEngine   = (int)KdfEngine,
                MacEngine   = (int)MacEngine,
                MacKeySize  = MacSize
            };

            Create(dsc, KeyParam);
        }
Exemplo n.º 20
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);
            }
        }
Exemplo n.º 21
0
        /// <summary>
        /// Get an uninitialized symmetric cipher from its description structure
        /// </summary>
        ///
        /// <param name="Description">The structure describing the symmetric cipher</param>
        ///
        /// <returns>An uninitialized symmetric cipher</returns>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if the Cipher type is not supported</exception>
        public static object GetInstance(CipherDescription Description)
        {
            switch ((SymmetricEngines)Description.EngineType)
            {
            case SymmetricEngines.RHX:
            case SymmetricEngines.SHX:
            case SymmetricEngines.THX:
            {
                return(CipherModeFromName.GetInstance((CipherModes)Description.CipherType, BlockCipherFromName.GetInstance((BlockCiphers)Description.EngineType, Description.BlockSize, Description.RoundCount, (Digests)Description.KdfEngine)));
            }

            case SymmetricEngines.ChaCha:
            case SymmetricEngines.Salsa:
            {
                return(StreamCipherFromName.GetInstance((StreamCiphers)Description.EngineType, Description.RoundCount));
            }

            default:
                throw new CryptoProcessingException("CipherFromDescription:GetInstance", "The symmetric cipher is not recognized!");
            }
        }
Exemplo n.º 22
0
        /// <summary>
        /// Initialize an empty VolumeKey structure; generates a random key tag identifier
        /// </summary>
        ///
        /// <param name="Description">The cipher description</param>
        /// <param name="Count">The number of key/vector pairs</param>
        public VolumeKey(CipherDescription Description, int Count)
        {
            this.Description = Description;
            this.Count       = Count;
            this.FileId      = new int[Count];
            this.State       = new byte[Count];
            this.Tag         = new CSPPrng().GetBytes(TAG_SIZE);
            int id = 0;

            using (CSPPrng rng = new CSPPrng())
            {
                this.Tag = rng.GetBytes(TAG_SIZE);
                id       = rng.Next();
            }

            for (int i = 0; i < Count; ++i)
            {
                this.State[i]  = (byte)VolumeKeyStates.Unassigned;
                this.FileId[i] = id + i;
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// Initialize the PackageKey structure using a Stream
        /// </summary>
        ///
        /// <param name="KeyStream">The Stream containing the PackageKey</param>
        public PackageKey(Stream KeyStream)
        {
            BinaryReader reader = new BinaryReader(KeyStream);

            KeyPolicy    = reader.ReadInt64();
            CreatedOn    = reader.ReadInt64();
            Authority    = new KeyAuthority(KeyStream);
            Description  = new CipherDescription(KeyStream);
            SubKeyCount  = reader.ReadInt32();
            SubKeyPolicy = new long[SubKeyCount];

            byte[] buffer = reader.ReadBytes(SubKeyCount * KEYPOL_SIZE);
            Buffer.BlockCopy(buffer, 0, SubKeyPolicy, 0, buffer.Length);

            buffer   = reader.ReadBytes(SubKeyCount * KEYID_SIZE);
            SubKeyID = new byte[SubKeyCount][];

            for (int i = 0; i < SubKeyCount; i++)
            {
                SubKeyID[i] = new byte[KEYID_SIZE];
                Buffer.BlockCopy(buffer, i * KEYID_SIZE, SubKeyID[i], 0, KEYID_SIZE);
            }
        }
Exemplo n.º 24
0
        /// <summary>
        /// Create a single use key file using a <see cref="KeyParams"/> containing the key material, and a <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.CipherDescription"/> containing the cipher implementation details
        /// </summary>
        ///
        /// <param name="Description">The <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.CipherDescription">Cipher Description</see> containing the cipher details</param>
        /// <param name="KeyParam">An initialized and populated key material container; must include a 16 byte populated ExtKey property</param>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if a KeyParams member is null, but specified in the Header or a Header parameter does not match a KeyParams value</exception>
        public void Create(CipherDescription Description, KeyParams KeyParam)
        {
            if (KeyParam.Key == null)
            {
                throw new CryptoProcessingException("KeyFactory:Create", "The key can not be null!", new ArgumentNullException());
            }

            if (KeyParam.Key.Length != Description.KeySize)
            {
                throw new CryptoProcessingException("KeyFactory:Create", "The key parameter does not match the key size specified in the Header!", new ArgumentOutOfRangeException());
            }

            if (Description.IvSize > 0 && KeyParam.IV != null)
            {
                if (KeyParam.IV.Length != Description.IvSize)
                {
                    throw new CryptoProcessingException("KeyFactory:Create", "The KeyParam IV size does not align with the IVSize setting in the Header!", new ArgumentOutOfRangeException());
                }
            }
            if (Description.MacKeySize > 0)
            {
                if (KeyParam.IKM == null)
                {
                    throw new CryptoProcessingException("KeyFactory:Create", "Digest key is specified in the header MacSize, but is null in KeyParam!", new ArgumentNullException());
                }
                if (KeyParam.IKM.Length != Description.MacKeySize)
                {
                    throw new CryptoProcessingException("KeyFactory:Create", "Header MacSize does not align with the size of the KeyParam IKM!", new ArgumentOutOfRangeException());
                }
            }

            byte[] hdr = new CipherKey(Description).ToBytes();
            m_keyStream.Write(hdr, 0, hdr.Length);
            byte[] key = ((MemoryStream)KeyParams.Serialize(KeyParam)).ToArray();
            m_keyStream.Write(key, 0, key.Length);
        }
Exemplo n.º 25
0
        private void CipherKeyTest()
        {
            CipherDescription ds = new CipherDescription(
                SymmetricEngines.RHX,
                192,
                IVSizes.V128,
                CipherModes.CTR,
                PaddingModes.PKCS7,
                BlockSizes.B128,
                RoundCounts.R22,
                Digests.Skein512,
                64,
                Digests.SHA512);

            CSPPrng rnd = new CSPPrng();

            byte[] id = new byte[16];
            byte[] ek = new byte[16];
            rnd.GetBytes(id);
            rnd.GetBytes(ek);

            // test serialization
            CipherKey ck = new CipherKey(ds, id, ek);

            byte[]    sk  = ck.ToBytes();
            CipherKey ck2 = new CipherKey(sk);

            if (!ck.Equals(ck2))
            {
                throw new Exception("KeyFactoryTest: CipherKey serialization has failed!");
            }

            MemoryStream mk  = ck.ToStream();
            CipherKey    ck3 = new CipherKey(mk);

            if (!ck.Equals(ck3))
            {
                throw new Exception("KeyFactoryTest: CipherKey serialization has failed!");
            }

            // test access funcs
            CipherKey.SetCipherDescription(mk, ds);
            CipherDescription ds2 = CipherKey.GetCipherDescription(mk);

            if (!ck.Description.Equals(ds2))
            {
                throw new Exception("KeyFactoryTest: CipherKey access has failed!");
            }

            rnd.GetBytes(ek);
            CipherKey.SetExtensionKey(mk, ek);
            if (!Evaluate.AreEqual(CipherKey.GetExtensionKey(mk), ek))
            {
                throw new Exception("KeyFactoryTest: CipherKey access has failed!");
            }

            rnd.GetBytes(id);
            CipherKey.SetKeyId(mk, id);
            if (!Evaluate.AreEqual(CipherKey.GetKeyId(mk), id))
            {
                throw new Exception("KeyFactoryTest: CipherKey access has failed!");
            }
        }
Exemplo n.º 26
0
 /// <summary>
 /// Set the CipherDescription structure
 /// </summary>
 ///
 /// <param name="KeyStream">The stream containing a key package</param>
 /// <param name="Description">The CipherDescription structure</param>
 public static void SetCipherDescription(Stream KeyStream, CipherDescription Description)
 {
     KeyStream.Seek(CPRDSC_SEEK, SeekOrigin.Begin);
     new BinaryWriter(KeyStream).Write(Description.ToBytes());
 }
Exemplo n.º 27
0
        /// <summary>
        /// Creates a temporary PackageKey on disk, extracts and compares the copy
        /// <para>Throws an Exception on failure</</para>
        /// </summary>
        public static void PackageFactoryTest()
        {
            string       path = GetTempPath();
            KeyGenerator kgen = new KeyGenerator();
            // populate a KeyAuthority structure
            KeyAuthority authority = new KeyAuthority(kgen.GetBytes(16), kgen.GetBytes(16), kgen.GetBytes(16), kgen.GetBytes(32), 0);

            // cipher paramaters
            CipherDescription desc = new CipherDescription(
                SymmetricEngines.RHX, 32,
                IVSizes.V128,
                CipherModes.CTR,
                PaddingModes.X923,
                BlockSizes.B128,
                RoundCounts.R14,
                Digests.Keccak512,
                64,
                Digests.Keccak512);

            // create the package key
            PackageKey pkey = new PackageKey(authority, desc, 10);

            // write a key file
            using (PackageFactory pf = new PackageFactory(new FileStream(path, FileMode.Open, FileAccess.ReadWrite), authority))
                pf.Create(pkey);

            for (int i = 0; i < pkey.SubKeyCount; i++)
            {
                CipherDescription desc2;
                KeyParams         kp1;
                KeyParams         kp2;
                byte[]            ext;
                byte[]            id = pkey.SubKeyID[i];

                // get at index
                using (FileStream stream = new FileStream(path, FileMode.Open, FileAccess.Read))
                    kp2 = PackageKey.AtIndex(stream, i);

                // read the package from id
                using (PackageFactory pf = new PackageFactory(new FileStream(path, FileMode.Open, FileAccess.ReadWrite), authority))
                    pf.Extract(id, out desc2, out kp1);

                // compare key material
                if (!Evaluate.AreEqual(kp1.Key, kp2.Key))
                {
                    throw new Exception();
                }
                if (!Evaluate.AreEqual(kp1.IV, kp2.IV))
                {
                    throw new Exception();
                }
                if (!desc.Equals(desc2))
                {
                    throw new Exception();
                }
            }
            if (File.Exists(path))
            {
                File.Delete(path);
            }
        }
Exemplo n.º 28
0
        /// <summary>
        /// Extract a subkey set (KeyParam), a file extension key, and a CipherDescription.
        /// <para>Used only when calling a Decryption function to get a specific subkey
        /// The KeyId field corresponds with the KeyId field contained in a MessageHeader structure.</para>
        /// </summary>
        ///
        /// <param name="KeyId">The KeyId array used to identify a subkey set; set as the KeyId in a MessageHeader structure</param>
        /// <param name="Description">out: The CipherDescription structure; the properties required to create a specific cipher instance</param>
        /// <param name="KeyParam">out: The KeyParams class containing a unique key, initialization vector and HMAC key</param>
        ///
        /// <exception cref="CryptoProcessingException">Thrown if the user has insufficient access rights to access this PackageKey, or the PackageKey does not contain the KeyId specified</exception>
        public void Extract(byte[] KeyId, out CipherDescription Description, out KeyParams KeyParam)
        {
            if (AccessScope.Equals(KeyScope.NoAccess))
            {
                throw new CryptoProcessingException("PackageFactory:Extract", "You do not have permission to access this key!", new UnauthorizedAccessException());
            }

            try
            {
                long keyPos;
                int  index;
                // get the key data
                MemoryStream keyStream = GetKeyStream();
                // get the keying materials starting offset within the key file
                keyPos = PackageKey.SubKeyOffset(keyStream, KeyId);

                if (keyPos == -1)
                {
                    throw new CryptoProcessingException("PackageFactory:Extract", "This package does not contain the key file!", new ArgumentException());
                }

                // get the index
                index = PackageKey.IndexFromId(keyStream, KeyId);
                // key flagged SingleUse was used for decryption and is locked out
                if (PackageKey.KeyHasPolicy(m_keyPackage.SubKeyPolicy[index], (long)PackageKeyStates.Locked) && !PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.VolumeKey))
                {
                    throw new CryptoProcessingException("PackageFactory:Extract", "SubKey is locked. The subkey has a single use policy and was previously used to decrypt the file.", new Exception());
                }
                // key flagged PostOverwrite was used for decryption and was erased
                if (PackageKey.KeyHasPolicy(m_keyPackage.SubKeyPolicy[index], (long)PackageKeyStates.Erased))
                {
                    throw new CryptoProcessingException("PackageFactory:Extract", "SubKey is erased. The subkey has a post erase policy and was previously used to decrypt the file.", new Exception());
                }

                // get the cipher description
                Description = m_keyPackage.Description;
                // get the keying material
                KeyParam = GetKeySet(keyStream, m_keyPackage.Description, keyPos);

                // test flags for overwrite or single use policies
                if (PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.PostOverwrite))
                {
                    PackageKey.SubKeySetPolicy(keyStream, index, (long)PackageKeyStates.Erased);
                }
                else if (PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.SingleUse))
                {
                    PackageKey.SubKeySetPolicy(keyStream, index, (long)PackageKeyStates.Locked);
                }

                // post overwrite flag set, erase the subkey
                if (PackageKey.KeyHasPolicy(KeyPolicy, (long)KeyPolicies.PostOverwrite))
                {
                    int keySize = Description.KeySize + Description.IvSize + Description.MacKeySize;
                    // overwrite the region within file
                    Erase(keyStream, keyPos, keySize);
                    // clear this section of the key
                    keyStream.Seek(keyPos, SeekOrigin.Begin);
                    keyStream.Write(new byte[keySize], 0, keySize);
                }

                // write to file
                WriteKeyStream(keyStream);
            }
            catch
            {
                throw;
            }
        }
Exemplo n.º 29
0
 /// <summary>
 /// Initialize the class with a CipherDescription Structure; containing the cipher implementation details.
 /// <para>This constructor creates and configures cryptographic instances based on the cipher description contained in a CipherDescription.
 /// Cipher modes, padding, and engine classes are destroyed automatically through this classes Dispose() method.</para>
 /// </summary>
 ///
 /// <param name="Header">A <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.CipherDescription"/> containing the cipher description</param>
 ///
 /// <exception cref="System.ArgumentException">Thrown if an invalid CipherDescription is used</exception>
 /// <exception cref="System.ArgumentNullException">Thrown if a null <see cref="VTDev.Libraries.CEXEngine.Crypto.Common.KeyParams">KeyParams</see> is used</exception>
 public CompressionCipher(CipherDescription Header)
     : base(Header)
 {
 }
Exemplo n.º 30
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;
            }
        }