Changeset 462


Ignore:
Timestamp:
11/6/2008 11:05:28 AM (6 years ago)
Author:
lowjoel
Message:

Cleaned up r443.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eraser6/Manager/PRNG.cs

    r443 r462  
    2727using System.Security.Cryptography; 
    2828using System.Runtime.InteropServices; 
     29using System.Diagnostics; 
     30using System.Reflection; 
     31using System.IO; 
     32using Microsoft.Win32.SafeHandles; 
    2933using Eraser.Util; 
    30 using Microsoft.Win32.SafeHandles; 
    31 using System.IO; 
    3234 
    3335namespace Eraser.Manager 
     
    214216    internal class EntropyThread 
    215217    { 
    216         public EntropyThread() 
    217         {            
    218             //Create the pool. 
    219             pool = new byte[poolSize]; // {512,1024} bytes 
    220  
    221             //Initialize the pool with some default information. 
    222             { 
    223                 //Process startup information 
    224                 KernelAPI.STARTUPINFO startupInfo = new KernelAPI.STARTUPINFO(); 
    225                 KernelAPI.GetStartupInfo(out startupInfo); 
    226                 AddEntropy(startupInfo); 
    227  
    228                 //System information 
    229                 KernelAPI.SYSTEM_INFO systemInfo = new KernelAPI.SYSTEM_INFO(); 
    230                 KernelAPI.GetSystemInfo(out systemInfo); 
    231                 AddEntropy(systemInfo); 
    232  
    233                 FastAddEntropy(); 
    234                 SlowAddEntropy(); 
    235  
    236                 // set the default PRF algorithm 
    237                 PRFAlgorithm = PRFAlgorithms.SHA512; 
    238                 MixPool(); 
    239             } 
    240  
    241             // apply whitening effect 
    242             PRFAlgorithm = PRFAlgorithms.RIPEMD160; 
    243             MixPool(); 
    244  
    245             // set back to default hash algorithm 
    246             PRFAlgorithm = PRFAlgorithms.SHA512; 
    247  
    248             //Then start the thread which maintains the pool. 
    249             thread = new Thread(delegate() 
    250                 { 
    251                     this.Main(); 
    252                 } 
    253             ); 
    254             thread.Start(); 
    255         } 
    256          
    257218        /// <summary> 
    258219        /// The algorithm used for mixing 
    259220        /// </summary> 
    260         public enum PRFAlgorithms : int 
     221        private enum PRFAlgorithms 
    261222        { 
    262223            MD5, 
     
    268229        }; 
    269230 
    270         /// <summary> 
    271         /// Property sheet for PRF algorithm 
    272         /// </summary> 
    273         public PRFAlgorithms PRFAlgorithm 
    274         { 
    275             get 
    276             { 
    277                 return prfAlgorithm; 
    278             } 
    279             set 
    280             { 
    281                 prfAlgorithm = value; 
    282             } 
     231        public EntropyThread() 
     232        { 
     233            //Create the pool. 
     234            pool = new byte[sizeof(uint) * 128]; 
     235 
     236            //Initialize the pool with some default information. 
     237            { 
     238                //Process startup information 
     239                KernelAPI.STARTUPINFO startupInfo = new KernelAPI.STARTUPINFO(); 
     240                KernelAPI.GetStartupInfo(out startupInfo); 
     241                AddEntropy(startupInfo); 
     242 
     243                //System information 
     244                KernelAPI.SYSTEM_INFO systemInfo = new KernelAPI.SYSTEM_INFO(); 
     245                KernelAPI.GetSystemInfo(out systemInfo); 
     246                AddEntropy(systemInfo); 
     247 
     248                FastAddEntropy(); 
     249                SlowAddEntropy(); 
     250 
     251                // set the default PRF algorithm 
     252                PRFAlgorithm = PRFAlgorithms.SHA512; 
     253                MixPool(); 
     254            } 
     255 
     256            // apply whitening effect 
     257            PRFAlgorithm = PRFAlgorithms.RIPEMD160; 
     258            MixPool(); 
     259 
     260            // set back to default hash algorithm 
     261            PRFAlgorithm = PRFAlgorithms.SHA512; 
     262 
     263            //Then start the thread which maintains the pool. 
     264            thread = new Thread(delegate() 
     265                { 
     266                    this.Main(); 
     267                } 
     268            ); 
     269            thread.Start(); 
    283270        } 
    284271 
     
    300287            //This entropy thread will utilize a polling loop. 
    301288            DateTime lastAddedEntropy = DateTime.Now; 
    302             TimeSpan ManagerEntropySpan = new TimeSpan(0, 10, 0); 
    303             System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch(); 
    304             while (thread.ThreadState != ThreadState.AbortRequested) 
     289            TimeSpan managerEntropySpan = new TimeSpan(0, 10, 0); 
     290            Stopwatch st = new Stopwatch(); 
     291 
     292            while (thread.ThreadState != System.Threading.ThreadState.AbortRequested) 
    305293            { 
    306294                st.Start(); 
     
    315303 
    316304                //Send entropy to the PRNGs for new seeds. 
    317                 if (DateTime.Now - lastAddedEntropy > ManagerEntropySpan) 
     305                if (DateTime.Now - lastAddedEntropy > managerEntropySpan) 
    318306                    ManagerLibrary.Instance.PRNGManager.AddEntropy(GetPool()); 
    319307            } 
     
    359347 
    360348        /// <summary> 
    361         /// Creates an instance of the requested PRF 
    362         /// </summary> 
    363         private void CheckPRF() 
    364         { 
    365             switch (prfAlgorithm) 
    366             { 
    367                 case PRFAlgorithms.MD5:         PRF = new MD5CryptoServiceProvider(); break; 
    368                 case PRFAlgorithms.SHA1:        PRF = new SHA1Managed(); break; 
    369                 case PRFAlgorithms.RIPEMD160:   PRF = new RIPEMD160Managed();  break; 
    370                 case PRFAlgorithms.SHA256:      PRF = new SHA256Managed();  break; 
    371                 case PRFAlgorithms.SHA384:      PRF = new SHA384Managed(); break; 
    372                 default: /*SHA512: */           PRF = new SHA512Managed(); break; 
    373             } 
    374         } 
    375  
    376         /// <summary> 
    377349        /// Mixes the contents of the pool. 
    378350        /// </summary> 
    379351        private void MixPool() 
    380352        { 
    381             CheckPRF(); 
    382  
    383353            lock (poolLock) 
    384354            { 
     
    421391                fixed (byte* pPool = pool) 
    422392                { 
    423                     //Add entropy to the pool by XORing every value with the given entropy. 
    424                     poolPosition = CircularMemoryXor(new IntPtr(pPool), new IntPtr(pEntropy), 
    425                                         poolPosition, poolSize, entropy.Length); 
    426                 } 
    427         } 
    428  
    429         /// <summary> 
    430         /// Optomised unmanaged circular memory xor 
    431         /// </summary> 
    432         /// <param name="dest">Destination Pointer</param> 
    433         /// <param name="source">Source Pointer</param> 
    434         /// <param name="size">Size in bytes</param> 
    435         private unsafe static int CircularMemoryXor(IntPtr destination, IntPtr source, 
    436             int destOffset, int destLength, int size) 
    437         { 
    438             uint* dest = (uint*)destination.ToPointer(); 
    439             uint* src = (uint*)source.ToPointer(); 
    440             while (size > 0) 
    441             { 
    442                 if (size + destOffset < destLength) 
    443                 { 
    444                     IntPtr _gc = new IntPtr(destination.ToInt32() + destOffset); 
    445                     MemoryXor(_gc, source, size); 
    446                     destOffset += size; 
    447                     size = 0; 
    448                 } 
    449                 else // (size + destOffset >= destLength) 
    450                 { 
    451                     IntPtr _gc = new IntPtr(destination.ToInt32() + destOffset); 
    452                     MemoryXor(_gc, source, destLength - destOffset); 
    453                     source = new IntPtr(source.ToInt32() + destLength - destOffset); 
    454                     size -= destLength - destOffset; 
    455                     destOffset = 0;                      
    456                 } 
    457             } 
    458  
    459             return destOffset; 
    460         } 
    461  
    462         private static unsafe void MemoryXor(IntPtr destination, IntPtr source, int size) 
    463         { 
    464             int wsize = size / sizeof(int); size -= wsize * sizeof(int); 
    465             uint* d = (uint*)destination.ToPointer(); 
    466             uint* s = (uint*)source.ToPointer(); 
     393                    int size = entropy.Length; 
     394                    byte* mpEntropy = pEntropy; 
     395                    while (size > 0) 
     396                    { 
     397                        //Bring the pool position back to the front if we are at our end 
     398                        if (poolPosition >= pool.Length) 
     399                            poolPosition = 0; 
     400 
     401                        int amountToMix = Math.Min(size, pool.Length - poolPosition); 
     402                        MemoryXor(pPool + poolPosition, mpEntropy, amountToMix); 
     403                        mpEntropy = mpEntropy + amountToMix; 
     404                        size -= amountToMix; 
     405                    } 
     406                } 
     407        } 
     408 
     409        /// <summary> 
     410        /// XOR's memory a DWORD at a time. 
     411        /// </summary> 
     412        /// <param name="destination">The destination buffer to be XOR'ed</param> 
     413        /// <param name="source">The source buffer to XOR with</param> 
     414        /// <param name="size">The size of the source buffer</param> 
     415        private static unsafe void MemoryXor(byte* destination, byte* source, int size) 
     416        { 
     417            int wsize = size / sizeof(uint); 
     418            size -= wsize * sizeof(uint); 
     419            uint* d = (uint*)destination; 
     420            uint* s = (uint*)source; 
    467421             
    468             while (wsize-- > 0) *d++ ^= *s++; 
     422            while (wsize-- > 0) 
     423                *d++ ^= *s++; 
    469424 
    470425            if (size > 0) 
    471426            { 
    472                 byte* db = (byte*)d, ds = (byte*)s; 
    473                 while (size-- > 0)  *db++ ^= *ds++; 
     427                byte* db = (byte*)d, 
     428                      ds = (byte*)s; 
     429                while (size-- > 0) 
     430                    *db++ ^= *ds++; 
    474431            } 
    475432        } 
     
    508465            } 
    509466        } 
    510 #if false 
    511          
    512         /// <summary> 
    513         /// Optomosed constant memory xor 
    514         /// </summary> 
    515         /// <param name="dest">Destination buffer</param> 
    516         /// <param name="value">value the destination should be xored against</param> 
    517         /// <param name="size">size of destination in bytes</param> 
    518         private static unsafe void MemoryXor(IntPtr dest, byte value, int size) 
    519         { 
    520             int wsize = size / sizeof(int); size -= wsize * sizeof(int); 
    521             uint* d = (uint*)dest.ToPointer(); 
    522             uint wvalue = 0; // a word containing values in  correct endian 
    523             for (int i = 0; i < sizeof(uint); i++, wvalue <<= 8)    wvalue |= value;             
    524  
    525             while (wsize-- > 0)     *d++ ^= wvalue; 
    526  
    527             if (size > 0) // size%4 == 0 ? 
    528             { 
    529                 byte* db = (byte*)d; 
    530                 while (size-- > 0) 
    531                     *db++ ^= value; 
    532             } 
    533         } 
    534 #endif 
    535467 
    536468        /// <summary> 
     
    713645        /// PRF algorithm handle 
    714646        /// </summary> 
    715         private HashAlgorithm PRF; 
     647        private HashAlgorithm PRF 
     648        { 
     649            get 
     650            { 
     651                Type type = null; 
     652                switch (PRFAlgorithm) 
     653                { 
     654                    case PRFAlgorithms.MD5: 
     655                        type = typeof(MD5CryptoServiceProvider); 
     656                        break; 
     657                    case PRFAlgorithms.SHA1: 
     658                        type = typeof(SHA1Managed); 
     659                        break; 
     660                    case PRFAlgorithms.RIPEMD160: 
     661                        type = typeof(RIPEMD160Managed); 
     662                        break; 
     663                    case PRFAlgorithms.SHA256: 
     664                        type = typeof(SHA256Managed); 
     665                        break; 
     666                    case PRFAlgorithms.SHA384: 
     667                        type = typeof(SHA384Managed); 
     668                        break; 
     669                    default: 
     670                        type = typeof(SHA512Managed); 
     671                        break; 
     672                } 
     673 
     674                if (type.IsInstanceOfType(prfCache)) 
     675                    return prfCache; 
     676                ConstructorInfo hashConstructor = type.GetConstructor(Type.EmptyTypes); 
     677                return prfCache = (HashAlgorithm)hashConstructor.Invoke(null); 
     678            } 
     679        } 
     680 
     681        /// <summary> 
     682        /// The last created PRF algorithm handle. 
     683        /// </summary> 
     684        private HashAlgorithm prfCache; 
    716685 
    717686        /// <summary> 
    718687        /// PRF algorithm identifier 
    719688        /// </summary> 
    720         private PRFAlgorithms prfAlgorithm;      
     689        private PRFAlgorithms PRFAlgorithm;      
    721690 
    722691        /// <summary> 
    723692        /// The thread object. 
    724693        /// </summary> 
    725         Thread thread; 
    726  
    727         /// <summary> 
    728         /// size of the netropy pool, should allways be exponent of 2. 
    729         /// </summary> 
    730         const int poolSize = sizeof(uint) * 128; 
    731  
    732         /// <summary> 
    733         /// Modulus of pool size 
    734         /// </summary> 
    735         const int poolMod = poolSize - 1; 
     694        private Thread thread; 
    736695 
    737696        /// <summary> 
    738697        /// The pool of data which we currently maintain. 
    739698        /// </summary> 
    740         byte[] pool; 
     699        private byte[] pool; 
    741700 
    742701        /// <summary> 
    743702        /// The next position where entropy will be added to the pool. 
    744703        /// </summary> 
    745         int poolPosition = 0; 
     704        private int poolPosition = 0; 
    746705 
    747706        /// <summary> 
    748707        /// The lock guarding the pool array and the current entropy addition index. 
    749708        /// </summary> 
    750         object poolLock = new object(); 
     709        private object poolLock = new object(); 
    751710    } 
    752711} 
Note: See TracChangeset for help on using the changeset viewer.