Exemplo n.º 1
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
        }
Exemplo n.º 2
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));
        }
Exemplo n.º 3
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;
        }
Exemplo n.º 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;
        }
Exemplo n.º 5
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;
        }
Exemplo n.º 6
0
        public IBuffer GetRandomBytes(int size)
        {
            var result = new byte[size];

            if (size > 0)
            {
                _cipher.Encrypt(result, result.Length, false);
            }

            return(result.AsBuffer());
        }
Exemplo n.º 7
0
        /// <summary>
        /// Get <paramref name="uRequestedCount" /> random bytes.
        /// </summary>
        /// <param name="uRequestedCount">Number of random bytes to retrieve.</param>
        /// <returns>Returns <paramref name="uRequestedCount" /> random bytes.</returns>
        public byte[] GetRandomBytes(uint uRequestedCount)
        {
            if (m_bDisposed)
            {
                throw new ObjectDisposedException(null);
            }

            if (uRequestedCount == 0)
            {
                return(MemUtil.EmptyByteArray);
            }
            if (uRequestedCount > (uint)int.MaxValue)
            {
                throw new ArgumentOutOfRangeException("uRequestedCount");
            }
            int cb = (int)uRequestedCount;

            byte[] pbRet = new byte[cb];

            if (m_crsAlgorithm == CrsAlgorithm.ChaCha20)
            {
                m_chacha20.Encrypt(pbRet, 0, cb);
            }
            else if (m_crsAlgorithm == CrsAlgorithm.Salsa20)
            {
                m_salsa20.Encrypt(pbRet, 0, cb);
            }
            else if (m_crsAlgorithm == CrsAlgorithm.ArcFourVariant)
            {
                unchecked
                {
                    for (int w = 0; w < cb; ++w)
                    {
                        ++m_i;
                        m_j += m_pbState[m_i];

                        byte t = m_pbState[m_i];                         // Swap entries
                        m_pbState[m_i] = m_pbState[m_j];
                        m_pbState[m_j] = t;

                        t        = (byte)(m_pbState[m_i] + m_pbState[m_j]);
                        pbRet[w] = m_pbState[t];
                    }
                }
            }
            else
            {
                Debug.Assert(false);
            }

            return(pbRet);
        }
Exemplo n.º 8
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;
        }
Exemplo n.º 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);
        }
Exemplo n.º 10
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);
        }
Exemplo n.º 11
0
        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));
        }
Exemplo n.º 12
0
        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);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Get <paramref name="uRequestedCount" /> random bytes.
        /// </summary>
        /// <param name="uRequestedCount">Number of random bytes to retrieve.</param>
        /// <returns>Returns <paramref name="uRequestedCount" /> random bytes.</returns>
        public byte[] GetRandomBytes(uint uRequestedCount)
        {
            if (uRequestedCount == 0)
            {
                return(new byte[0]);
            }

            byte[] pbRet = new byte[uRequestedCount];

            if (m_crsAlgorithm == CrsAlgorithm.ArcFourVariant)
            {
                unchecked
                {
                    for (uint w = 0; w < uRequestedCount; ++w)
                    {
                        ++m_i;
                        m_j += m_pbState[m_i];

                        byte t = m_pbState[m_i];                         // Swap entries
                        m_pbState[m_i] = m_pbState[m_j];
                        m_pbState[m_j] = t;

                        t        = (byte)(m_pbState[m_i] + m_pbState[m_j]);
                        pbRet[w] = m_pbState[t];
                    }
                }
            }
            else if (m_crsAlgorithm == CrsAlgorithm.Salsa20)
            {
                m_salsa20.Encrypt(pbRet, pbRet.Length, false);
            }
            else
            {
                Debug.Assert(false);
            }

            return(pbRet);
        }
        /// <summary>
        /// Get <paramref name="uRequestedCount" /> random bytes.
        /// </summary>
        /// <param name="uRequestedCount">Number of random bytes to retrieve.</param>
        /// <returns>Returns <paramref name="uRequestedCount" /> random bytes.</returns>
        public byte[] GetRandomBytes(uint uRequestedCount)
        {
            if (uRequestedCount == 0)
            {
                return(new byte[0]);
            }

            byte[] pbRet = new byte[uRequestedCount];

            if (crsAlgorithm == CrsAlgorithm.ArcFourVariant)
            {
                unchecked
                {
                    for (uint w = 0; w < uRequestedCount; ++w)
                    {
                        ++firstCounter;
                        secondCounter += state[firstCounter];

                        byte t = state[firstCounter];                         // Swap entries
                        state[firstCounter]  = state[secondCounter];
                        state[secondCounter] = t;

                        t        = (byte)(state[firstCounter] + state[secondCounter]);
                        pbRet[w] = state[t];
                    }
                }
            }
            else if (crsAlgorithm == CrsAlgorithm.Salsa20)
            {
                salsa20.Encrypt(pbRet, pbRet.Length, false);
            }
            else
            {
                Debug.Assert(false);
            }

            return(pbRet);
        }
Exemplo n.º 15
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
        }