Changeset 462
- Timestamp:
- 11/6/2008 11:05:28 AM (5 years ago)
- File:
-
- 1 edited
-
branches/eraser6/Manager/PRNG.cs (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/eraser6/Manager/PRNG.cs
r443 r462 27 27 using System.Security.Cryptography; 28 28 using System.Runtime.InteropServices; 29 using System.Diagnostics; 30 using System.Reflection; 31 using System.IO; 32 using Microsoft.Win32.SafeHandles; 29 33 using Eraser.Util; 30 using Microsoft.Win32.SafeHandles;31 using System.IO;32 34 33 35 namespace Eraser.Manager … … 214 216 internal class EntropyThread 215 217 { 216 public EntropyThread()217 {218 //Create the pool.219 pool = new byte[poolSize]; // {512,1024} bytes220 221 //Initialize the pool with some default information.222 {223 //Process startup information224 KernelAPI.STARTUPINFO startupInfo = new KernelAPI.STARTUPINFO();225 KernelAPI.GetStartupInfo(out startupInfo);226 AddEntropy(startupInfo);227 228 //System information229 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 algorithm237 PRFAlgorithm = PRFAlgorithms.SHA512;238 MixPool();239 }240 241 // apply whitening effect242 PRFAlgorithm = PRFAlgorithms.RIPEMD160;243 MixPool();244 245 // set back to default hash algorithm246 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 257 218 /// <summary> 258 219 /// The algorithm used for mixing 259 220 /// </summary> 260 p ublic enum PRFAlgorithms : int221 private enum PRFAlgorithms 261 222 { 262 223 MD5, … … 268 229 }; 269 230 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(); 283 270 } 284 271 … … 300 287 //This entropy thread will utilize a polling loop. 301 288 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) 305 293 { 306 294 st.Start(); … … 315 303 316 304 //Send entropy to the PRNGs for new seeds. 317 if (DateTime.Now - lastAddedEntropy > ManagerEntropySpan)305 if (DateTime.Now - lastAddedEntropy > managerEntropySpan) 318 306 ManagerLibrary.Instance.PRNGManager.AddEntropy(GetPool()); 319 307 } … … 359 347 360 348 /// <summary> 361 /// Creates an instance of the requested PRF362 /// </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>377 349 /// Mixes the contents of the pool. 378 350 /// </summary> 379 351 private void MixPool() 380 352 { 381 CheckPRF();382 383 353 lock (poolLock) 384 354 { … … 421 391 fixed (byte* pPool = pool) 422 392 { 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; 467 421 468 while (wsize-- > 0) *d++ ^= *s++; 422 while (wsize-- > 0) 423 *d++ ^= *s++; 469 424 470 425 if (size > 0) 471 426 { 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++; 474 431 } 475 432 } … … 508 465 } 509 466 } 510 #if false511 512 /// <summary>513 /// Optomosed constant memory xor514 /// </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 endian523 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 #endif535 467 536 468 /// <summary> … … 713 645 /// PRF algorithm handle 714 646 /// </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; 716 685 717 686 /// <summary> 718 687 /// PRF algorithm identifier 719 688 /// </summary> 720 private PRFAlgorithms prfAlgorithm;689 private PRFAlgorithms PRFAlgorithm; 721 690 722 691 /// <summary> 723 692 /// The thread object. 724 693 /// </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; 736 695 737 696 /// <summary> 738 697 /// The pool of data which we currently maintain. 739 698 /// </summary> 740 byte[] pool;699 private byte[] pool; 741 700 742 701 /// <summary> 743 702 /// The next position where entropy will be added to the pool. 744 703 /// </summary> 745 int poolPosition = 0;704 private int poolPosition = 0; 746 705 747 706 /// <summary> 748 707 /// The lock guarding the pool array and the current entropy addition index. 749 708 /// </summary> 750 object poolLock = new object();709 private object poolLock = new object(); 751 710 } 752 711 }
Note: See TracChangeset
for help on using the changeset viewer.
