|
|
1.1 ! root 1: /* ! 2: * True random number computation and storage ! 3: * ! 4: * (c) Copyright 1990-1994 by Philip Zimmermann. All rights reserved. ! 5: * The author assumes no liability for damages resulting from the use ! 6: * of this software, even if the damage results from defects in this ! 7: * software. No warranty is expressed or implied. ! 8: * ! 9: * Note that while most PGP source modules bear Philip Zimmermann's ! 10: * copyright notice, many of them have been revised or entirely written ! 11: * by contributors who frequently failed to put their names in their ! 12: * code. Code that has been incorporated into PGP from other authors ! 13: * was either originally published in the public domain or is used with ! 14: * permission from the various authors. ! 15: * ! 16: * PGP is available for free to the public under certain restrictions. ! 17: * See the PGP User's Guide (included in the release package) for ! 18: * important information about licensing, patent restrictions on ! 19: * certain algorithms, trademarks, copyrights, and export controls. ! 20: * ! 21: * Written by Colin Plumb. ! 22: */ ! 23: #include <stdlib.h> ! 24: ! 25: #include "randpool.h" ! 26: #include "usuals.h" ! 27: #include "md5.h" ! 28: ! 29: /* The pool must be a multiple of the 16-byte (128-bit) MD5 block size */ ! 30: #define RANDPOOLBYTES ((RANDPOOLBITS+127 & ~127) >> 3) ! 31: #if RANDPOOLBYTES <= 64 ! 32: #error Random pool too small - please increase RANDPOOLBITS in randpool.h ! 33: #endif ! 34: ! 35: static byte randPool[RANDPOOLBYTES]; /* Random pool */ ! 36: static unsigned randPoolGetPos = 0; /* Current position to get from */ ! 37: static unsigned randPoolAddPos = 0; /* Current position to add to */ ! 38: ! 39: static byte randPoolKey[64]; ! 40: ! 41: static void ! 42: xorbytes(byte *dest, byte const *src, unsigned len) ! 43: { ! 44: while (len--) ! 45: *dest++ = *src++; ! 46: } ! 47: ! 48: /* ! 49: * Destroys already-used random numbers. Ensures no sensitive data ! 50: * remains in memory that can be recovered later. This is also ! 51: * called to "stir in" newly acquired environmental noise bits. ! 52: * These noise bits are placed in the trueRandKey. ! 53: * ! 54: * The transformation is carried out by "encrypting" the data in CBC ! 55: * mode with MD5 as the block cipher. This is not invertible, but that ! 56: * is just fine for these purposes. ! 57: * ! 58: * Then, to make doubly certain the stirring operation is strictly one-way, ! 59: * we destroy the key. This is done by reinitializing it from the pool, ! 60: * copying the first 64 bytes of the pool over the key. These bytes are ! 61: * not returned by randPoolGetBytes(). ! 62: */ ! 63: void ! 64: randPoolStir(void) ! 65: { ! 66: int i; ! 67: ! 68: xorbytes(randPool, randPool+sizeof(randPool)-16, 16); ! 69: MD5Transform((word32 *)randPool, (word32 *)randPoolKey); ! 70: for(i = 16; i < sizeof(randPool); i += 16) { ! 71: xorbytes(randPool+i, randPool+i-16, 16); ! 72: MD5Transform((word32 *)(randPool+i), (word32 *)randPoolKey); ! 73: } ! 74: ! 75: memcpy(randPoolKey, randPool, sizeof(randPoolKey)); ! 76: ! 77: randPoolAddPos = 0; ! 78: randPoolGetPos = sizeof(randPoolKey); ! 79: } ! 80: ! 81: void ! 82: randPoolAddBytes(byte const *buf, unsigned len) ! 83: { ! 84: unsigned t; ! 85: ! 86: while (len > (t = sizeof(randPool) - randPoolAddPos)) { ! 87: xorbytes(randPool+randPoolAddPos, buf, t); ! 88: buf += t; ! 89: len -= t; ! 90: randPoolStir(); ! 91: } ! 92: ! 93: if (len) { ! 94: xorbytes(randPool+randPoolAddPos, buf, len); ! 95: randPoolAddPos += len; ! 96: randPoolGetPos = sizeof(randPool); ! 97: } ! 98: } ! 99: ! 100: void ! 101: randPoolGetBytes(byte *buf, unsigned len) ! 102: { ! 103: unsigned t; ! 104: ! 105: while (len > (t = sizeof(randPool) - randPoolGetPos)) { ! 106: memcpy(buf, randPool+randPoolGetPos, t); ! 107: buf += t; ! 108: len -= t; ! 109: randPoolStir(); ! 110: } ! 111: ! 112: if (len) { ! 113: memcpy(buf, randPool+randPoolGetPos, len); ! 114: randPoolGetPos += len; ! 115: } ! 116: } ! 117: ! 118: byte ! 119: randPoolGetByte(void) ! 120: { ! 121: if (randPoolGetPos == sizeof(randPool)) ! 122: randPoolStir(); ! 123: ! 124: return randPool[randPoolGetPos++]; ! 125: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.