示例#1
0
        private void Decrypt()
        {
            if (m_pbData.Length == 0)
            {
                return;
            }

            if (m_mp == PbMemProt.ProtectedMemory)
            {
                ProtectedMemory.Unprotect(m_pbData, MemoryProtectionScope.SameProcess);
            }
            else if (m_mp == PbMemProt.Salsa20)
            {
                Salsa20Cipher s = new Salsa20Cipher(g_pbKey32,
                                                    BitConverter.GetBytes(m_lID));
                s.Encrypt(m_pbData, m_pbData.Length, true);
                s.Dispose();
            }
            else if (m_mp == PbMemProt.ExtCrypt)
            {
                m_fExtCrypt(m_pbData, PbCryptFlags.Decrypt, m_lID);
            }
            else
            {
                Debug.Assert(m_mp == PbMemProt.None);
            }

            m_mp = PbMemProt.None;
        }
        /// <summary>
        /// Creates a cipher instance (<see cref="ChaCha20Cipher"/> or <see cref="Salsa20Cipher"/> (KeePass older as 2.35)) with the nonce and the pin as key.
        /// </summary>
        /// <param name="pin">The pin to use as key.</param>
        /// <param name="nonce">The nonce to use as IV.</param>
        /// <returns>The cipher instance.</returns>
        private static CtrBlockCipher CreateCipher(byte[] pin, byte[] nonce)
        {
            Contract.Requires(pin != null);
            Contract.Requires(nonce != null);
            Contract.Ensures(Contract.Result <ChaCha20Cipher>() != null);

            var key = new byte[32];

            using (var h = new SHA512Managed())
            {
                var hashBytes = h.ComputeHash(pin);
                Array.Copy(hashBytes, key, 32);

                MemUtil.ZeroByteArray(hashBytes);
            }

            CtrBlockCipher cipher;

            if (nonce.Length == 12 /*>= KeePass 2.35*/)
            {
                cipher = new ChaCha20Cipher(key, nonce, false);
            }
            else
            {
                cipher = new Salsa20Cipher(key, nonce);
            }

            MemUtil.ZeroByteArray(key);

            return(cipher);
        }
示例#3
0
        private static void TestSalsa20()
        {
            // Test values from official set 6, vector 3
            byte[] pbKey = new byte[32]
            {
                0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
                0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC,
                0x3F, 0x92, 0xE5, 0x38, 0x8B, 0xDE, 0x31, 0x84,
                0xD7, 0x2A, 0x7D, 0xD0, 0x23, 0x76, 0xC9, 0x1C
            };
            byte[] pbIV = new byte[8]
            {
                0x28, 0x8F, 0xF6, 0x5D,
                0xC4, 0x2B, 0x92, 0xF9
            };
            byte[] pbExpected = new byte[16]
            {
                0x5E, 0x5E, 0x71, 0xF9, 0x01, 0x99, 0x34, 0x03,
                0x04, 0xAB, 0xB2, 0x2A, 0x37, 0xB6, 0x62, 0x5B
            };

            byte[]        pb = new byte[16];
            Salsa20Cipher c  = new Salsa20Cipher(pbKey, pbIV);

            c.Encrypt(pb, pb.Length, false);
            if (!MemUtil.ArraysEqual(pb, pbExpected))
            {
                throw new SecurityException("Salsa20.");
            }

#if DEBUG
            // Extended test in debug mode
            byte[] pbExpected2 = new byte[16]
            {
                0xAB, 0xF3, 0x9A, 0x21, 0x0E, 0xEE, 0x89, 0x59,
                0x8B, 0x71, 0x33, 0x37, 0x70, 0x56, 0xC2, 0xFE
            };
            byte[] pbExpected3 = new byte[16]
            {
                0x1B, 0xA8, 0x9D, 0xBD, 0x3F, 0x98, 0x83, 0x97,
                0x28, 0xF5, 0x67, 0x91, 0xD5, 0xB7, 0xCE, 0x23
            };

            Random r    = new Random();
            int    nPos = Salsa20ToPos(c, r, pb.Length, 65536);
            c.Encrypt(pb, pb.Length, false);
            if (!MemUtil.ArraysEqual(pb, pbExpected2))
            {
                throw new SecurityException("Salsa20-2.");
            }

            nPos = Salsa20ToPos(c, r, nPos + pb.Length, 131008);
            Array.Clear(pb, 0, pb.Length);
            c.Encrypt(pb, pb.Length, true);
            if (!MemUtil.ArraysEqual(pb, pbExpected3))
            {
                throw new SecurityException("Salsa20-3.");
            }
#endif
        }
示例#4
0
        private void Decrypt()
        {
            if (passwordData.Length == 0)
            {
                return;
            }

            if (passwordMemoryProtection == PbMemProt.ProtectedMemory)
            {
                ProtectedMemory.Unprotect(passwordData, MemoryProtectionScope.SameProcess);
            }
            else if (passwordMemoryProtection == PbMemProt.Salsa20)
            {
                var cipher = new Salsa20Cipher(keyBytes32, BitConverter.GetBytes(longId));
                cipher.Encrypt(passwordData, passwordData.Length, true);
                cipher.Dispose();
            }
            else if (passwordMemoryProtection == PbMemProt.ExtCrypt)
            {
                m_fExtCrypt(passwordData, PbCryptFlags.Decrypt, longId);
            }
            else
            {
                Debug.Assert(passwordMemoryProtection == PbMemProt.None);
            }

            passwordMemoryProtection = PbMemProt.None;
        }
示例#5
0
        public void TestSalsa20Cipher()
        {
            var r = CryptoRandom.NewWeakRandom();

            // Test values from official set 6, vector 3
            var pbKey = new byte[] {
                0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
                0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC,
                0x3F, 0x92, 0xE5, 0x38, 0x8B, 0xDE, 0x31, 0x84,
                0xD7, 0x2A, 0x7D, 0xD0, 0x23, 0x76, 0xC9, 0x1C
            };
            var pbIv = new byte[] { 0x28, 0x8F, 0xF6, 0x5D,
                                    0xC4, 0x2B, 0x92, 0xF9 };
            var pbExpected = new byte[] {
                0x5E, 0x5E, 0x71, 0xF9, 0x01, 0x99, 0x34, 0x03,
                0x04, 0xAB, 0xB2, 0x2A, 0x37, 0xB6, 0x62, 0x5B
            };

            var pb = new byte[16];
            var c  = new Salsa20Cipher(pbKey, pbIv);

            c.Encrypt(pb, 0, pb.Length);
            Assert.That(MemUtil.ArraysEqual(pb, pbExpected), Is.True);

            // Extended test
            var pbExpected2 = new byte[] {
                0xAB, 0xF3, 0x9A, 0x21, 0x0E, 0xEE, 0x89, 0x59,
                0x8B, 0x71, 0x33, 0x37, 0x70, 0x56, 0xC2, 0xFE
            };
            var pbExpected3 = new byte[] {
                0x1B, 0xA8, 0x9D, 0xBD, 0x3F, 0x98, 0x83, 0x97,
                0x28, 0xF5, 0x67, 0x91, 0xD5, 0xB7, 0xCE, 0x23
            };

            var nPos = Salsa20ToPos(c, r, pb.Length, 65536);

            Array.Clear(pb, 0, pb.Length);
            c.Encrypt(pb, 0, pb.Length);
            Assert.That(MemUtil.ArraysEqual(pb, pbExpected2), Is.True);

            Salsa20ToPos(c, r, nPos + pb.Length, 131008);
            Array.Clear(pb, 0, pb.Length);
            c.Encrypt(pb, 0, pb.Length);
            Assert.That(MemUtil.ArraysEqual(pb, pbExpected3), Is.True);

            var       d       = new Dictionary <string, bool>();
            const int nRounds = 100;

            for (var i = 0; i < nRounds; ++i)
            {
                var z = new byte[32];
                c = new Salsa20Cipher(z, MemUtil.Int64ToBytes(i));
                c.Encrypt(z, 0, z.Length);
                d[MemUtil.ByteArrayToHexString(z)] = true;
            }
            Assert.That(d.Count, Is.EqualTo(nRounds));
        }
示例#6
0
        private void Encrypt()
        {
            Debug.Assert(m_mp == PbMemProt.None);

            // Nothing to do if caller didn't request protection
            if (!m_bProtected)
            {
                return;
            }

            // ProtectedMemory.Protect throws for data size == 0
            if (m_pbData.Length == 0)
            {
                return;
            }

            PbCryptDelegate f = g_fExtCrypt;

            if (f != null)
            {
                f(m_pbData, PbCryptFlags.Encrypt, m_lID);

                m_fExtCrypt = f;
                m_mp        = PbMemProt.ExtCrypt;
                return;
            }

            if (ProtectedBinary.ProtectedMemorySupported)
            {
                ProtectedMemory.Protect(m_pbData, MemoryProtectionScope.SameProcess);

                m_mp = PbMemProt.ProtectedMemory;
                return;
            }

            byte[] pbKey32 = g_pbKey32;
            if (pbKey32 == null)
            {
                pbKey32 = CryptoRandom.Instance.GetRandomBytes(32);

                byte[] pbUpd = Interlocked.Exchange <byte[]>(ref g_pbKey32, pbKey32);
                if (pbUpd != null)
                {
                    pbKey32 = pbUpd;
                }
            }

            Salsa20Cipher s = new Salsa20Cipher(pbKey32,
                                                BitConverter.GetBytes(m_lID));

            s.Encrypt(m_pbData, m_pbData.Length, true);
            s.Dispose();
            m_mp = PbMemProt.Salsa20;
        }
示例#7
0
        private void Encrypt()
        {
            Debug.Assert(passwordMemoryProtection == PbMemProt.None);

            if (!isProtected)
            {
                return;
            }

            if (passwordData.Length == 0)
            {
                return;
            }

            var f = encryptionDelegate;

            if (f != null)
            {
                f(passwordData, PbCryptFlags.Encrypt, longId);

                m_fExtCrypt = f;
                passwordMemoryProtection = PbMemProt.ExtCrypt;
                return;
            }

            if (ProtectedMemorySupported)
            {
                ProtectedMemory.Protect(passwordData, MemoryProtectionScope.SameProcess);

                passwordMemoryProtection = PbMemProt.ProtectedMemory;
                return;
            }

            var pbKey32 = keyBytes32;

            if (pbKey32 == null)
            {
                pbKey32 = CryptoRandom.Instance.GetRandomBytes(32);

                var pbUpd = Interlocked.Exchange(ref keyBytes32, pbKey32);
                if (pbUpd != null)
                {
                    pbKey32 = pbUpd;
                }
            }

            var cipher = new Salsa20Cipher(pbKey32, BitConverter.GetBytes(longId));

            cipher.Encrypt(passwordData, passwordData.Length, true);
            cipher.Dispose();
            passwordMemoryProtection = PbMemProt.Salsa20;
        }
示例#8
0
        private static int Salsa20ToPos(Salsa20Cipher c, Random r, int nPos,
                                        int nTargetPos)
        {
            var pb = new byte[512];

            while (nPos < nTargetPos)
            {
                var x    = r.Next(1, 513);
                var nGen = Math.Min(nTargetPos - nPos, x);
                c.Encrypt(pb, 0, nGen);
                nPos += nGen;
            }

            return(nTargetPos);
        }
示例#9
0
        private static int Salsa20ToPos(Salsa20Cipher c, Random r, int nPos,
                                        int nTargetPos)
        {
            byte[] pb = new byte[512];

            while (nPos < nTargetPos)
            {
                int x    = r.Next(1, 513);
                int nGen = Math.Min(nTargetPos - nPos, x);
                c.Encrypt(pb, nGen, r.Next(0, 2) == 0);
                nPos += nGen;
            }

            return(nTargetPos);
        }
示例#10
0
文件: OtpUtil.cs 项目: 77rusa/README
        public static string EncryptData(byte[] pbData, byte[] pbKey32,
                                         byte[] pbIV16)
        {
            byte[] pbIV8 = new byte[8];
            Array.Copy(pbIV16, 0, pbIV8, 0, 8);

            byte[] pbEnc = new byte[pbData.Length];
            Array.Copy(pbData, pbEnc, pbData.Length);

            Salsa20Cipher enc = new Salsa20Cipher(pbKey32, pbIV8);

            enc.Encrypt(pbEnc, 0, pbEnc.Length);

            return("s20://" + Convert.ToBase64String(pbEnc,
                                                     Base64FormattingOptions.None));
        }
        public Salsa20RandomGenerator(IBuffer key)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }

            key = HashAlgorithmProvider
                  .OpenAlgorithm(HashAlgorithmNames.Sha256)
                  .HashData(key);

            var iv = new byte[]
            {
                0xE8, 0x30, 0x09, 0x4B,
                0x97, 0x20, 0x5D, 0x2A
            };

            _cipher = new Salsa20Cipher(key.ToArray(), iv);
        }
示例#12
0
文件: OtpUtil.cs 项目: 77rusa/README
        public static byte[] DecryptData(string strData, byte[] pbKey32,
                                         byte[] pbIV16)
        {
            if (!strData.StartsWith("s20://"))
            {
                return(null);
            }

            string strEnc = strData.Substring(6);

            byte[] pb = Convert.FromBase64String(strEnc);

            byte[] pbIV8 = new byte[8];
            Array.Copy(pbIV16, 0, pbIV8, 0, 8);

            Salsa20Cipher dec = new Salsa20Cipher(pbKey32, pbIV8);

            dec.Encrypt(pb, 0, pb.Length);

            return(pb);
        }
示例#13
0
        /// <summary>
        /// Construct a new cryptographically secure random stream object.
        /// </summary>
        /// <param name="genAlgorithm">Algorithm to use.</param>
        /// <param name="pbKey">Initialization key. Must not be <c>null</c> and
        /// must contain at least 1 byte.</param>
        /// <exception cref="System.ArgumentNullException">Thrown if the
        /// <paramref name="pbKey" /> parameter is <c>null</c>.</exception>
        /// <exception cref="System.ArgumentException">Thrown if the
        /// <paramref name="pbKey" /> parameter contains no bytes or the
        /// algorithm is unknown.</exception>
        public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey)
        {
            m_crsAlgorithm = genAlgorithm;

            Debug.Assert(pbKey != null); if (pbKey == null)
            {
                throw new ArgumentNullException("pbKey");
            }

            uint uKeyLen = (uint)pbKey.Length;

            Debug.Assert(uKeyLen != 0); if (uKeyLen == 0)
            {
                throw new ArgumentException();
            }

            if (genAlgorithm == CrsAlgorithm.ArcFourVariant)
            {
                m_pbState = ComputeArcFourState(pbKey, uKeyLen);

                GetRandomBytes(512);                 // Increases security, see cryptanalysis
            }
            else if (genAlgorithm == CrsAlgorithm.Salsa20)
            {
                SHA256Managed sha256  = new SHA256Managed();
                byte[]        pbKey32 = sha256.ComputeHash(pbKey);
                byte[]        pbIV    = new byte[] { 0xE8, 0x30, 0x09, 0x4B,
                                                     0x97, 0x20, 0x5D, 0x2A }; // Unique constant

                m_salsa20 = new Salsa20Cipher(pbKey32, pbIV);
            }
            else             // Unknown algorithm
            {
                Debug.Assert(false);
                throw new ArgumentException();
            }
        }
示例#14
0
        /// <summary>
        /// Construct a new cryptographically secure random stream object.
        /// </summary>
        /// <param name="genAlgorithm">Algorithm to use.</param>
        /// <param name="pbKey">Initialization key. Must not be <c>null</c> and
        /// must contain at least 1 byte.</param>
        /// <exception cref="System.ArgumentNullException">Thrown if the
        /// <paramref name="pbKey" /> parameter is <c>null</c>.</exception>
        /// <exception cref="System.ArgumentException">Thrown if the
        /// <paramref name="pbKey" /> parameter contains no bytes or the
        /// algorithm is unknown.</exception>
        public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey)
        {
            m_crsAlgorithm = genAlgorithm;

            Debug.Assert(pbKey != null); if (pbKey == null)
            {
                throw new ArgumentNullException("pbKey");
            }

            uint uKeyLen = (uint)pbKey.Length;

            Debug.Assert(uKeyLen != 0); if (uKeyLen == 0)
            {
                throw new ArgumentException();
            }

            if (genAlgorithm == CrsAlgorithm.ArcFourVariant)
            {
                // Fill the state linearly
                m_pbState = new byte[256];
                for (uint w = 0; w < 256; ++w)
                {
                    m_pbState[w] = (byte)w;
                }

                unchecked
                {
                    byte j = 0, t;
                    uint inxKey = 0;
                    for (uint w = 0; w < 256; ++w)                    // Key setup
                    {
                        j += (byte)(m_pbState[w] + pbKey[inxKey]);

                        t            = m_pbState[0];              // Swap entries
                        m_pbState[0] = m_pbState[j];
                        m_pbState[j] = t;

                        ++inxKey;
                        if (inxKey >= uKeyLen)
                        {
                            inxKey = 0;
                        }
                    }
                }

                GetRandomBytes(512);                 // Increases security, see cryptanalysis
            }
            else if (genAlgorithm == CrsAlgorithm.Salsa20)
            {
                SHA256Managed sha256  = new SHA256Managed();
                byte[]        pbKey32 = sha256.ComputeHash(pbKey);
                byte[]        pbIV    = new byte[] { 0xE8, 0x30, 0x09, 0x4B,
                                                     0x97, 0x20, 0x5D, 0x2A }; // Unique constant

                m_salsa20 = new Salsa20Cipher(pbKey32, pbIV);
            }
            else             // Unknown algorithm
            {
                Debug.Assert(false);
                throw new ArgumentException();
            }
        }
示例#15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CryptoRandomStream"/> class.
        /// Construct a new cryptographically secure random stream object.
        /// </summary>
        /// <param name="genAlgorithm">
        /// Algorithm to use.
        /// </param>
        /// <param name="pbKey">
        /// Initialization key. Must not be <c>null</c> and
        /// must contain at least 1 byte.
        /// </param>
        /// <exception cref="System.ArgumentNullException">
        /// Thrown if the
        /// <paramref name="pbKey"/> parameter is <c>null</c>.
        /// </exception>
        /// <exception cref="System.ArgumentException">
        /// Thrown if the
        /// <paramref name="pbKey"/> parameter contains no bytes or the
        /// algorithm is unknown.
        /// </exception>
        public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey)
        {
            this.m_crsAlgorithm = genAlgorithm;

            Debug.Assert(pbKey != null);
            if (pbKey == null)
            {
                throw new ArgumentNullException("pbKey");
            }

            uint uKeyLen = (uint)pbKey.Length;

            Debug.Assert(uKeyLen != 0);
            if (uKeyLen == 0)
            {
                throw new ArgumentException();
            }

            if (genAlgorithm == CrsAlgorithm.ArcFourVariant)
            {
                // Fill the state linearly
                this.m_pbState = new byte[256];
                for (uint w = 0; w < 256; ++w)
                {
                    this.m_pbState[w] = (byte)w;
                }

                unchecked
                {
                    byte j = 0, t;
                    uint inxKey = 0;
                    for (uint w = 0; w < 256; ++w)
                    {
                        // Key setup
                        j += (byte)(this.m_pbState[w] + pbKey[inxKey]);

                        t = this.m_pbState[0]; // Swap entries
                        this.m_pbState[0] = this.m_pbState[j];
                        this.m_pbState[j] = t;

                        ++inxKey;
                        if (inxKey >= uKeyLen)
                        {
                            inxKey = 0;
                        }
                    }
                }

                this.GetRandomBytes(512); // Increases security, see cryptanalysis
            }
            else if (genAlgorithm == CrsAlgorithm.Salsa20)
            {
                var sha256 = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256);

                byte[] pbKey32 = sha256.HashData(pbKey.AsBuffer()).ToArray();
                byte[] pbIV    = new byte[] { 0xE8, 0x30, 0x09, 0x4B, 0x97, 0x20, 0x5D, 0x2A }; // Unique constant

                this.m_salsa20 = new Salsa20Cipher(pbKey32, pbIV);
            }
            else
            {
                // Unknown algorithm
                Debug.Assert(false);
                throw new ArgumentException();
            }
        }
示例#16
0
        public ISingleCipherTransform GetCipherTransformer()
        {
            if (m_SymAlgo == SymAlgoCode.AES256 || m_SymAlgo == SymAlgoCode.ThreeDES || m_SymAlgo == SymAlgoCode.Twofish)
            {
                SymmetricAlgorithm SymAlgo;

                if (m_SymAlgo == SymAlgoCode.ThreeDES)
                {
                    SymAlgo = new TripleDESCryptoServiceProvider
                    {
                        BlockSize = 64,
                        IV        = m_IV,
                        KeySize   = 192,
                        Key       = m_Key,
                        Mode      = CipherMode.CBC,
                        Padding   = PaddingMode.None
                    };
                }
                else if (m_SymAlgo == SymAlgoCode.AES256)
                {
                    SymAlgo = new RijndaelManaged
                    {
                        BlockSize = 128,
                        IV        = m_IV,
                        KeySize   = 256,
                        Key       = m_Key,
                        Mode      = CipherMode.CBC,
                        Padding   = PaddingMode.None
                    }
                }
                ;
                else
                {
                    SymAlgo = new TwofishManaged
                    {
                        BlockSize = 128,
                        IV        = m_IV,
                        KeySize   = 256,
                        Key       = m_Key,
                        Mode      = CipherMode.CBC,
                        Padding   = PaddingMode.None
                    }
                };

                return(new CryptoTransformer(SymAlgo));
            }
            else if (m_SymAlgo == SymAlgoCode.ChaCha20 || m_SymAlgo == SymAlgoCode.Salsa20)
            {
                CtrBlockCipher c;

                if (m_SymAlgo == SymAlgoCode.ChaCha20)
                {
                    c = new ChaCha20Cipher(m_Key, m_IV);
                }
                else
                {
                    c = new Salsa20Cipher(m_Key, m_IV);
                }

                return(new CtrBlockCipherTransformer(c));
            }


            throw new SecurityException("Invalid Algorithm");
        }
示例#17
0
        /// <summary>
        /// Construct a new cryptographically secure random stream object.
        /// </summary>
        /// <param name="a">Algorithm to use.</param>
        /// <param name="pbKey">Initialization key. Must not be <c>null</c> and
        /// must contain at least 1 byte.</param>
        public CryptoRandomStream(CrsAlgorithm a, byte[] pbKey)
        {
            if (pbKey == null)
            {
                Debug.Assert(false); throw new ArgumentNullException("pbKey");
            }

            int cbKey = pbKey.Length;

            if (cbKey <= 0)
            {
                Debug.Assert(false);                 // Need at least one byte
                throw new ArgumentOutOfRangeException("pbKey");
            }

            m_crsAlgorithm = a;

            if (a == CrsAlgorithm.ChaCha20)
            {
                byte[] pbKey32 = new byte[32];
                byte[] pbIV12  = new byte[12];

                using (SHA512Managed h = new SHA512Managed())
                {
                    byte[] pbHash = h.ComputeHash(pbKey);
                    Array.Copy(pbHash, pbKey32, 32);
                    Array.Copy(pbHash, 32, pbIV12, 0, 12);
                    MemUtil.ZeroByteArray(pbHash);
                }

                m_chacha20 = new ChaCha20Cipher(pbKey32, pbIV12, true);
            }
            else if (a == CrsAlgorithm.Salsa20)
            {
                byte[] pbKey32 = CryptoUtil.HashSha256(pbKey);
                byte[] pbIV8   = new byte[8] {
                    0xE8, 0x30, 0x09, 0x4B,
                    0x97, 0x20, 0x5D, 0x2A
                };                                                // Unique constant

                m_salsa20 = new Salsa20Cipher(pbKey32, pbIV8);
            }
            else if (a == CrsAlgorithm.ArcFourVariant)
            {
                // Fill the state linearly
                m_pbState = new byte[256];
                for (int w = 0; w < 256; ++w)
                {
                    m_pbState[w] = (byte)w;
                }

                unchecked
                {
                    byte j = 0, t;
                    int  inxKey = 0;
                    for (int w = 0; w < 256; ++w)                    // Key setup
                    {
                        j += (byte)(m_pbState[w] + pbKey[inxKey]);

                        t            = m_pbState[0];              // Swap entries
                        m_pbState[0] = m_pbState[j];
                        m_pbState[j] = t;

                        ++inxKey;
                        if (inxKey >= cbKey)
                        {
                            inxKey = 0;
                        }
                    }
                }

                GetRandomBytes(512); // Increases security, see cryptanalysis
            }
            else                     // Unknown algorithm
            {
                Debug.Assert(false);
                throw new ArgumentOutOfRangeException("a");
            }
        }
示例#18
0
        private static void TestSalsa20()
        {
            // Test values from official set 6, vector 3
            byte[] pbKey = new byte[32] {
                0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
                0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC,
                0x3F, 0x92, 0xE5, 0x38, 0x8B, 0xDE, 0x31, 0x84,
                0xD7, 0x2A, 0x7D, 0xD0, 0x23, 0x76, 0xC9, 0x1C
            };
            byte[] pbIV = new byte[8] {
                0x28, 0x8F, 0xF6, 0x5D,
                0xC4, 0x2B, 0x92, 0xF9
            };
            byte[] pbExpected = new byte[16] {
                0x5E, 0x5E, 0x71, 0xF9, 0x01, 0x99, 0x34, 0x03,
                0x04, 0xAB, 0xB2, 0x2A, 0x37, 0xB6, 0x62, 0x5B
            };

            byte[]        pb = new byte[16];
            Salsa20Cipher c  = new Salsa20Cipher(pbKey, pbIV);

            c.Encrypt(pb, pb.Length, false);
            if (!MemUtil.ArraysEqual(pb, pbExpected))
            {
                throw new SecurityException("Salsa20-1");
            }

#if DEBUG
            // Extended test in debug mode
            byte[] pbExpected2 = new byte[16] {
                0xAB, 0xF3, 0x9A, 0x21, 0x0E, 0xEE, 0x89, 0x59,
                0x8B, 0x71, 0x33, 0x37, 0x70, 0x56, 0xC2, 0xFE
            };
            byte[] pbExpected3 = new byte[16] {
                0x1B, 0xA8, 0x9D, 0xBD, 0x3F, 0x98, 0x83, 0x97,
                0x28, 0xF5, 0x67, 0x91, 0xD5, 0xB7, 0xCE, 0x23
            };

            Random r    = new Random();
            int    nPos = Salsa20ToPos(c, r, pb.Length, 65536);
            c.Encrypt(pb, pb.Length, false);
            if (!MemUtil.ArraysEqual(pb, pbExpected2))
            {
                throw new SecurityException("Salsa20-2");
            }

            nPos = Salsa20ToPos(c, r, nPos + pb.Length, 131008);
            Array.Clear(pb, 0, pb.Length);
            c.Encrypt(pb, pb.Length, true);
            if (!MemUtil.ArraysEqual(pb, pbExpected3))
            {
                throw new SecurityException("Salsa20-3");
            }

            Dictionary <string, bool> d = new Dictionary <string, bool>();
            const int nRounds           = 100;
            for (int i = 0; i < nRounds; ++i)
            {
                byte[] z = new byte[32];
                c = new Salsa20Cipher(z, BitConverter.GetBytes((long)i));
                c.Encrypt(z, z.Length, true);
                d[MemUtil.ByteArrayToHexString(z)] = true;
            }
            if (d.Count != nRounds)
            {
                throw new SecurityException("Salsa20-4");
            }
#endif
        }