Exemple #1
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="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 != KEYID_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;
            }
        }
Exemple #2
0
        /// <summary>
        /// Creates a temporary CipherKey on disk, extracts and compares the copy
        /// <para>Throws an Exception on failure</</para>
        /// </summary>
        public static void KeyFactoryTest()
        {
            string path = GetTempPath();
            KeyParams key1;
            KeyParams key2;
            CipherKey cikey;
            CipherDescription desc;

            using (KeyFactory factory = new KeyFactory(path))
            {
                // create a key/iv
                key1 = new KeyGenerator().GetKeyParams(32, 16, 64);

                // alt: manual creation
                /*kf.Create(
                    kp,
                    Engines.RDX,
                    32,
                    IVSizes.V128,
                    CipherModes.CTR,
                    PaddingModes.X923,
                    BlockSizes.B128,
                    RoundCounts.R14,
                    Digests.Keccak512,
                    64,
                    Digests.Keccak512);*/

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

                // create the key
                factory.Create(desc, key1);
                // extract
                factory.Extract(out cikey, out key2);
            }

            if (!cikey.Description.Equals(desc))
                throw new Exception();
            // compare key material
            if (!Compare.AreEqual(key1.IKM, key2.IKM))
                throw new Exception();
            if (!Compare.AreEqual(key1.IV, key2.IV))
                throw new Exception();
            if (!Compare.AreEqual(key1.Key, key2.Key))
                throw new Exception();

            if (File.Exists(path))
                File.Delete(path);
        }
Exemple #3
0
        /// <summary>
        /// Compare this object instance with another
        /// </summary>
        ///
        /// <param name="Obj">Object to compare</param>
        ///
        /// <returns>True if equal, otherwise false</returns>
        public override bool Equals(Object Obj)
        {
            if (!(Obj is CipherDescription))
            {
                return(false);
            }

            CipherDescription other = (CipherDescription)Obj;

            if (EngineType != other.EngineType)
            {
                return(false);
            }
            if (KeySize != other.KeySize)
            {
                return(false);
            }
            if (IvSize != other.IvSize)
            {
                return(false);
            }
            if (CipherType != other.CipherType)
            {
                return(false);
            }
            if (PaddingType != other.PaddingType)
            {
                return(false);
            }
            if (BlockSize != other.BlockSize)
            {
                return(false);
            }
            if (RoundCount != other.RoundCount)
            {
                return(false);
            }
            if (KdfEngine != other.KdfEngine)
            {
                return(false);
            }
            if (MacKeySize != other.MacKeySize)
            {
                return(false);
            }
            if (MacEngine != other.MacEngine)
            {
                return(false);
            }

            return(true);
        }
Exemple #4
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);
        }
Exemple #5
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>
        /// <param name="ExtensionKey">out: The random key used to encrypt the message file extension</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, out byte[] ExtensionKey)
        {
            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 = _keyPackage.Description;
                // get the file extension key
                ExtensionKey = _keyPackage.ExtensionKey;
                // store the subkey identity, this is written into the message header to identify the subkey
                byte[] keyId = _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, _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;
            }
        }
Exemple #6
0
 /// <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 engine classes are destroyed automatically through this classes Dispose() method.</para>
 /// </summary>
 /// 
 /// <param name="Encryption">Cipher is an encryptor</param>
 /// <param name="Header">A <see cref="CipherDescription"/> containing the cipher description</param>
 /// <param name="KeyParam">A <see cref="KeyParams"/> class containing the encryption Key material</param>
 /// 
 /// <exception cref="System.ArgumentException">Thrown if an invalid <see cref="CipherDescription">CipherDescription</see> is used</exception>
 /// <exception cref="System.ArgumentNullException">Thrown if a null <see cref="KeyParams">KeyParams</see> is used</exception>
 public CompressionCipher(bool Encryption, CipherDescription Header, KeyParams KeyParam)
     : base(Encryption, Header, KeyParam)
 {
     _isCompression = Encryption;
 }
Exemple #7
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>
        /// <param name="ExtensionKey">out: The random key used to encrypt the message file extension</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, out byte[] ExtensionKey)
        {
            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(_keyPackage.SubKeyPolicy[index], (long)PackageKeyStates.Locked))
                    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(_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 = _keyPackage.Description;
                // get the keying material
                KeyParam = GetKeySet(keyStream, _keyPackage.Description, keyPos);
                // encrypts the file extension
                ExtensionKey = _keyPackage.ExtensionKey;

                // 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.MacSize;
                    // overwrite the region within file
                    Erase(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;
            }
        }
Exemple #8
0
        /// <summary>
        /// Create a single use key file using a <see cref="KeyParams"/> containing the key material, and a <see cref="CipherDescription"/> containing the cipher implementation details
        /// </summary>
        /// 
        /// <param name="Description">The <see cref="CipherDescription">Cipher Description</see> containing the cipher details</param>
        /// <param name="KeyParam">An initialized and populated key material container</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.MacSize > 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.MacSize)
                    throw new CryptoProcessingException("KeyFactory:Create", "Header MacSize does not align with the size of the KeyParam IKM!", new ArgumentOutOfRangeException());
            }

            if (_keyStream == null)
                _keyStream = new FileStream(_keyPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read);

            byte[] hdr = new CipherKey(Description).ToBytes();
            _keyStream.Write(hdr, 0, hdr.Length);
            byte[] key = ((MemoryStream)KeyParams.Serialize(KeyParam)).ToArray();
            _keyStream.Write(key, 0, key.Length);
        }
Exemple #9
0
        /// <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="CipherDescription"/> containing the cipher description</param>
        /// <param name="KeyParam">A <see cref="KeyParams"/> class containing the encryption Key material</param>
        /// 
        /// <exception cref="CryptoProcessingException">Thrown if an invalid <see cref="CipherDescription">CipherDescription</see> or <see cref="KeyParams">KeyParams</see> 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());

            _disposeEngine = true;
            _isEncryption = Encryption;
            _blockSize = Description.BlockSize;
            _isParallel = false;

            if (_isStreamCipher = IsStreamCipher((SymmetricEngines)Description.EngineType))
            {
                _streamCipher = GetStreamEngine((SymmetricEngines)Description.EngineType, Description.RoundCount, (Digests)Description.KdfEngine);
                _streamCipher.Initialize(KeyParam);

                if (_streamCipher.GetType().Equals(typeof(Fusion)))
                {
                    if (_isParallel = ((Fusion)_streamCipher).IsParallel)
                        _blockSize = ((Fusion)_streamCipher).ParallelBlockSize;
                }
            }
            else
            {
                _cipherEngine = GetCipher((CipherModes)Description.CipherType, (SymmetricEngines)Description.EngineType, Description.RoundCount, Description.BlockSize, (Digests)Description.KdfEngine);
                _cipherEngine.Initialize(_isEncryption, KeyParam);

                if (_isCounterMode = _cipherEngine.GetType().Equals(typeof(CTR)))
                {
                    if (_isParallel = ((CTR)_cipherEngine).IsParallel)
                        _blockSize = ((CTR)_cipherEngine).ParallelBlockSize;
                }
                else
                {
                    if (_cipherEngine.GetType().Equals(typeof(CBC)))
                    {
                        if (_isParallel = ((CBC)_cipherEngine).IsParallel && !((CBC)_cipherEngine).IsEncryption)
                            _blockSize = ((CBC)_cipherEngine).ParallelBlockSize;
                    }
                    else if (_cipherEngine.GetType().Equals(typeof(CFB)))
                    {
                        if (_isParallel = ((CFB)_cipherEngine).IsParallel && !((CFB)_cipherEngine).IsEncryption)
                            _blockSize = ((CFB)_cipherEngine).ParallelBlockSize;
                    }
                }
            }
        }
Exemple #10
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="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="CipherDescription">Cipher Description</see> containing the cipher implementation details</param>
        /// <param name="SeedEngine">The <see cref="Prngs">Random Generator</see> used to create the stage I seed material during key generation.</param>
        /// <param name="HashEngine">The <see cref="Digests">Digest Engine</see> used in the stage II phase of key generation.</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, Prngs SeedEngine = Prngs.CSPRng, Digests HashEngine = VTDev.Libraries.CEXEngine.Crypto.Enumeration.Digests.SHA512)
        {
            KeyParams keyParam;

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

            Create(Description, keyParam);
        }
Exemple #11
0
 /// <summary>
 /// Get this is a valid header file
 /// </summary>
 ///
 /// <param name="Description">The stream containing a key header</param>
 ///
 /// <returns>Valid</returns>
 public static bool IsValid(CipherDescription Description)
 {
     // not guaranteed, but should be ok
     return(Description.EngineType < Enum.GetValues(typeof(SymmetricEngines)).Length << 2);
 }
Exemple #12
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);
            ExtensionKey = reader.ReadBytes(EXTKEY_SIZE);
            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);
            }
        }
Exemple #13
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(DESC_SEEK, SeekOrigin.Begin);
     new BinaryWriter(KeyStream).Write(Description.ToBytes());
 }
Exemple #14
0
        /// <summary>
        /// Test the VolumeCipher class implementation
        /// </summary>
        public static void VolumeCipherTest(string InputDirectory)
        {
            string[] paths = DirectoryTools.GetFiles(InputDirectory);

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

            // define the volume key
            VolumeKey vkey = new VolumeKey(desc, paths.Length);

            // key will be written to this stream
            MemoryStream keyStream = new MemoryStream();

            // create the volume key stream
            using (VolumeFactory vf = new VolumeFactory(keyStream))
                vf.Create(vkey);

            // encrypt the files in the directory
            using (VolumeCipher vc = new VolumeCipher(true, keyStream))
                vc.Transform(paths);

            // decrypt the files
            using (VolumeCipher vc = new VolumeCipher(false, keyStream))
                vc.Transform(paths);

            // manual inspection of files..
        }
Exemple #15
0
        /// <remarks>
        /// Returns the populated KeyParams class
        /// </remarks>
        private KeyParams GetKeySet(MemoryStream KeyStream, CipherDescription Description, long Position)
        {
            KeyParams keyParam;
            KeyStream.Seek(Position, SeekOrigin.Begin);

            // create the keyparams class
            if (Description.MacSize > 0 && Description.IvSize > 0)
            {
                byte[] key = new byte[Description.KeySize];
                byte[] iv = new byte[Description.IvSize];
                byte[] ikm = new byte[Description.MacSize];

                KeyStream.Read(key, 0, key.Length);
                KeyStream.Read(iv, 0, iv.Length);
                KeyStream.Read(ikm, 0, ikm.Length);
                keyParam = new KeyParams(key, iv, ikm);
            }
            else if (Description.IvSize > 0)
            {
                byte[] key = new byte[Description.KeySize];
                byte[] iv = new byte[Description.IvSize];

                KeyStream.Read(key, 0, key.Length);
                KeyStream.Read(iv, 0, iv.Length);
                keyParam = new KeyParams(key, iv);
            }
            else if (Description.MacSize > 0)
            {
                byte[] key = new byte[Description.KeySize];
                byte[] ikm = new byte[Description.MacSize];

                KeyStream.Read(key, 0, key.Length);
                KeyStream.Read(ikm, 0, ikm.Length);
                keyParam = new KeyParams(key, null, ikm);
            }
            else
            {
                byte[] key = new byte[Description.KeySize];
                KeyStream.Read(key, 0, key.Length);
                keyParam = new KeyParams(key);
            }

            return keyParam;
        }
Exemple #16
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.RDX, 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(path, 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))
                    kp2 = PackageKey.AtIndex(stream, i);

                // read the package from id
                using (PackageFactory pf = new PackageFactory(path, authority))
                    pf.Extract(id, out desc2, out kp1, out ext);

                // compare key material
                if (!Compare.AreEqual(kp1.Key, kp2.Key))
                    throw new Exception();
                if (!Compare.AreEqual(kp1.IV, kp2.IV))
                    throw new Exception();
                if (!Compare.AreEqual(pkey.ExtensionKey, ext))
                    throw new Exception();
                if (!desc.Equals(desc2))
                    throw new Exception();
            }
            if (File.Exists(path))
                File.Delete(path);
        }
Exemple #17
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 Int32[Count];
     this.State = new byte[Count];
 }
Exemple #18
0
        /// <summary>
        /// Creates a temporary VolumeKey on disk, extracts and compares the copy
        /// <para>Throws an Exception on failure</</para>
        /// </summary>
        public static void VolumeFactoryTest()
        {
            string path = GetTempPath();

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

            // create the package key
            VolumeKey vkey = new VolumeKey(desc, 10);
            // add id's
            for (int i = 0; i < vkey.FileId.Length; i++)
                vkey.FileId[i] = i;

            // write a key file
            using (VolumeFactory vf = new VolumeFactory(path))
                vf.Create(vkey);

            for (int i = 0; i < vkey.Count; i++)
            {
                CipherDescription desc2;
                KeyParams kp1;
                KeyParams kp2;

                using (FileStream stream = new FileStream(path, FileMode.Open))
                    kp1 = VolumeKey.AtIndex(stream, i);

                int id = vkey.FileId[i];

                // read the package
                using (VolumeFactory vf = new VolumeFactory(path))
                    vf.Extract(id, out desc2, out kp2);

                // compare key material
                if (!Compare.AreEqual(kp1.Key, kp2.Key))
                    throw new Exception();
                if (!Compare.AreEqual(kp1.IV, kp2.IV))
                    throw new Exception();
                if (!desc.Equals(desc2))
                    throw new Exception();
            }
            if (File.Exists(path))
                File.Delete(path);
        }
Exemple #19
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.Tag = new VTDev.Libraries.CEXEngine.Crypto.Prng.CSPRng().GetBytes(32);
     this.Description = Description;
     this.Count = Count;
     this.FileId = new Int32[Count];
     this.State = new byte[Count];
 }
Exemple #20
0
        /// <summary>
        /// Initialize the VolumeKey structure using a Stream
        /// </summary>
        /// 
        /// <param name="KeyStream">The Stream containing the VolumeKey</param>
        public VolumeKey(Stream KeyStream)
        {
            BinaryReader reader = new BinaryReader(KeyStream);

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

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

            State = reader.ReadBytes(Count);
        }
Exemple #21
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="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>
        /// <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 an invalid ExtensionKey is used</exception>
        public PackageKey(KeyAuthority Authority, CipherDescription Cipher, int SubKeyCount, byte[] ExtensionKey = null)
        {
            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();
            }

            if (ExtensionKey != null)
            {
                if (ExtensionKey.Length != 16)
                    throw new CryptoProcessingException("PackageKey:CTor", "Extension key must be exactly 16 bytes in length!", new ArgumentOutOfRangeException());

                this.ExtensionKey = ExtensionKey;
            }
            else
            {
                using (CSPRng rand = new CSPRng())
                    this.ExtensionKey = rand.GetBytes(16);
            }

            CreatedOn = DateTime.Now.Ticks;
        }
Exemple #22
0
 /// <summary>
 /// Create a volume key file using a <see cref="CipherDescription"/> containing the cipher implementation details, and a key count size
 /// </summary>
 /// 
 /// <param name="Description">The <see cref="CipherDescription">Cipher Description</see> containing the cipher details</param>
 /// <param name="KeyCount">The number of key sets associated with this volume key</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>
 public void Create(CipherDescription Description, int KeyCount)
 {
     this.Create(new VolumeKey(Description, KeyCount));
 }
Exemple #23
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(KeyStream);
            KeyID = reader.ReadBytes(KEYID_SIZE);
            ExtensionKey = reader.ReadBytes(EXTKEY_SIZE);
        }
Exemple #24
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="SymmetricEngines">Engine</see> type</param>
        /// <param name="KeySize">The cipher Key Size in bytes</param>
        /// <param name="IvSize">Size of the cipher <see cref="IVSizes">Initialization Vector</see></param>
        /// <param name="CipherType">The type of <see cref="CipherModes">Cipher Mode</see></param>
        /// <param name="PaddingType">The type of cipher <see cref="PaddingModes">Padding Mode</see></param>
        /// <param name="BlockSize">The cipher <see cref="BlockSizes">Block Size</see></param>
        /// <param name="Rounds">The number of diffusion <see cref="RoundCounts">Rounds</see></param>
        /// <param name="KdfEngine">The <see cref="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="Digests">Digest</see> engine used to authenticate a message file encrypted with this key</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>
        public void Create(int KeyCount, 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,
                MacSize = MacSize
            };

            Create(dsc, KeyCount);
        }
Exemple #25
0
        /// <summary>
        /// Extract a KeyParams and CipherDescription
        /// </summary>
        /// 
        /// <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(int Index, out CipherDescription Description, out KeyParams KeyParam)
        {
            if (!string.IsNullOrEmpty(_keyPath))
            {
                if (!File.Exists(_keyPath))
                    throw new CryptoProcessingException("VolumeFactory:Extract", "The key file could not be found! Check the path.", new FileNotFoundException());
            }

            if (_keyStream == null)
                _keyStream = new FileStream(_keyPath, FileMode.Open, FileAccess.Read);

            VolumeKey vkey = new VolumeKey(_keyStream);
            Description = vkey.Description;
            KeyParam = VolumeKey.AtIndex(_keyStream, Index);
        }
Exemple #26
0
 /// <summary>
 /// Get this is a valid header file
 /// </summary>
 /// 
 /// <param name="Description">The stream containing a key header</param>
 /// 
 /// <returns>Valid</returns>
 public static bool IsValid(CipherDescription Description)
 {
     // not guaranteed, but should be ok
     return (Description.EngineType < Enum.GetValues(typeof(SymmetricEngines)).Length);
 }