Changeset 2572


Ignore:
Timestamp:
3/22/2012 3:29:12 AM (3 years ago)
Author:
lowjoel
Message:

Added a priority list for the primary and secondary hash algorithms. Favour the Crypto Next Gen APIs first, since they have higher speed on Vista+, fallback to the CryptoAPI implementations if they can't be created, and finally use the Managed implementations if the above two fail.

Should close #406.

Location:
trunk/eraser/Eraser.Manager
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser/Eraser.Manager/EntropyPoller.cs

    r2571 r2572  
    3232using Eraser.Plugins; 
    3333using Eraser.Plugins.ExtensionPoints; 
     34using Eraser.Util; 
    3435 
    3536namespace Eraser.Manager 
     
    134135            //running under an OS with FIPS-compliance mode the RIPEMD-160 algorithm cannot 
    135136            //be used. 
    136             try 
    137             { 
    138                 using (HashAlgorithm hash = new RIPEMD160Managed()) 
    139                     MixPool(hash); 
    140             } 
    141             catch (InvalidOperationException) 
    142             { 
    143             } 
     137            HashAlgorithm secondaryHash = GetSecondaryHash(); 
     138            if (secondaryHash != null) 
     139                MixPool(secondaryHash); 
    144140        } 
    145141 
     
    215211        private void MixPool() 
    216212        { 
    217             using (HashAlgorithm hash = new SHA1CryptoServiceProvider()) 
    218                 MixPool(hash); 
     213            MixPool(GetPrimaryHash()); 
    219214        } 
    220215 
     
    314309 
    315310        /// <summary> 
     311        /// Gets the primary hash algorithm used for pool mixing. 
     312        /// </summary> 
     313        /// <returns>A hash algorithm suitable for the current platform serving as the 
     314        /// primary hash algorithm for pool mixing.</returns> 
     315        /// <remarks>The instance returned need not be freed as it is cached.</remarks> 
     316        private static HashAlgorithm GetPrimaryHash() 
     317        { 
     318            if (PrimaryHashAlgorithmCache != null) 
     319                return PrimaryHashAlgorithmCache; 
     320 
     321            HashFactoryDelegate[] priorityList = new HashFactoryDelegate[] { 
     322                delegate() { return new SHA512Cng(); }, 
     323                delegate() { return new SHA512CryptoServiceProvider(); }, 
     324                delegate() { return new SHA512Managed(); }, 
     325                delegate() { return new SHA256Cng(); }, 
     326                delegate() { return new SHA256CryptoServiceProvider(); }, 
     327                delegate() { return new SHA256Managed(); }, 
     328                delegate() { return new SHA1Cng(); }, 
     329                delegate() { return new SHA1CryptoServiceProvider(); }, 
     330                delegate() { return new SHA1Managed(); } 
     331            }; 
     332 
     333            foreach (HashFactoryDelegate func in priorityList) 
     334            { 
     335                try 
     336                { 
     337                    return PrimaryHashAlgorithmCache = func(); 
     338                } 
     339                catch (InvalidOperationException) 
     340                { 
     341                } 
     342            } 
     343 
     344            throw new InvalidOperationException(S._("No suitable hash algorithms were found " + 
     345                "on this computer.")); 
     346        } 
     347 
     348        /// <summary> 
     349        /// Gets the secondary hash algorithm used for pool mixing, serving roughly analogous 
     350        /// to key whitening. 
     351        /// </summary> 
     352        /// <returns>A hash algorithm suitable for the current platform serving as the 
     353        /// secondary hash algorithm for pool mixing, or null if no secondary hash 
     354        /// algorithm can be used (e.g. due to FIPS algorithm restrictions)</returns> 
     355        /// <remarks>The instance returned need not be freed as it is cached.</remarks> 
     356        private static HashAlgorithm GetSecondaryHash() 
     357        { 
     358            if (HasSecondaryHashAlgorithm) 
     359                return SecondaryHashAlgorithmCache; 
     360 
     361            HashFactoryDelegate[] priorityList = new HashFactoryDelegate[] { 
     362                delegate() { return new RIPEMD160Managed(); } 
     363            }; 
     364 
     365            foreach (HashFactoryDelegate func in priorityList) 
     366            { 
     367                try 
     368                { 
     369                    SecondaryHashAlgorithmCache = func(); 
     370                    HasSecondaryHashAlgorithm = true; 
     371                    return SecondaryHashAlgorithmCache; 
     372                } 
     373                catch (InvalidOperationException) 
     374                { 
     375                } 
     376            } 
     377 
     378            return null; 
     379        } 
     380 
     381        /// <summary> 
     382        /// The function prototype for factory delegates in the Primary and Secondary hash 
     383        /// priority lists. 
     384        /// </summary> 
     385        /// <returns></returns> 
     386        private delegate HashAlgorithm HashFactoryDelegate(); 
     387 
     388        /// <summary> 
    316389        /// The pool of data which we currently maintain. 
    317390        /// </summary> 
     
    343416        /// </summary> 
    344417        private List<IEntropySource> EntropySources = new List<IEntropySource>(); 
     418 
     419        /// <summary> 
     420        /// Cache object for <see cref="GetPrimaryHash"/> 
     421        /// </summary> 
     422        private static HashAlgorithm PrimaryHashAlgorithmCache; 
     423 
     424        /// <summary> 
     425        /// Cache object for <see cref="GetSecondaryHash"/> 
     426        /// </summary> 
     427        private static HashAlgorithm SecondaryHashAlgorithmCache; 
     428 
     429        /// <summary> 
     430        /// Cache for whether construction for a <see cref="SecondaryHashAlgorithmCache"/> 
     431        /// has been attempted. 
     432        /// </summary> 
     433        private static bool HasSecondaryHashAlgorithm; 
    345434    } 
    346435} 
  • trunk/eraser/Eraser.Manager/Strings.en.resx

    r2511 r2572  
    118118    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> 
    119119  </resheader> 
     120  <data name="No suitable hash algorithms were found on this computer." xml:space="preserve"> 
     121    <value>(Untranslated)</value> 
     122  </data> 
    120123  <data name="Running on restart" xml:space="preserve"> 
    121124    <value>Running on restart</value> 
  • trunk/eraser/Eraser.Manager/Strings.it.resx

    r2511 r2572  
    118118    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> 
    119119  </resheader> 
     120  <data name="No suitable hash algorithms were found on this computer." xml:space="preserve"> 
     121    <value>(Untranslated)</value> 
     122  </data> 
    120123  <data name="Running on restart" xml:space="preserve"> 
    121124    <value>Esecuzione al riavvio</value> 
  • trunk/eraser/Eraser.Manager/Strings.nl.resx

    r2511 r2572  
    118118    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> 
    119119  </resheader> 
     120  <data name="No suitable hash algorithms were found on this computer." xml:space="preserve"> 
     121    <value>(Untranslated)</value> 
     122  </data> 
    120123  <data name="Running on restart" xml:space="preserve"> 
    121124    <value>(Untranslated)</value> 
  • trunk/eraser/Eraser.Manager/Strings.pl.resx

    r2511 r2572  
    118118    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> 
    119119  </resheader> 
     120  <data name="No suitable hash algorithms were found on this computer." xml:space="preserve"> 
     121    <value>(Untranslated)</value> 
     122  </data> 
    120123  <data name="Running on restart" xml:space="preserve"> 
    121124    <value>Uruchomienie po restarcie</value> 
  • trunk/eraser/Eraser.Manager/Strings.resx

    r2511 r2572  
    118118    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> 
    119119  </resheader> 
     120  <data name="No suitable hash algorithms were found on this computer." xml:space="preserve"> 
     121    <value>No suitable hash algorithms were found on this computer.</value> 
     122  </data> 
    120123  <data name="Running on restart" xml:space="preserve"> 
    121124    <value>Running on restart</value> 
Note: See TracChangeset for help on using the changeset viewer.