CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

RNDSTRAW.CPP (20973B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 /* $Header: /CounterStrike/RNDSTRAW.CPP 1     3/03/97 10:25a Joe_bostic $ */
     17 /***********************************************************************************************
     18  ***              C O N F I D E N T I A L  ---  W E S T W O O D  S T U D I O S               ***
     19  ***********************************************************************************************
     20  *                                                                                             *
     21  *                 Project Name : Command & Conquer                                            *
     22  *                                                                                             *
     23  *                    File Name : RNDSTRAW.CPP                                                 *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : 07/04/96                                                     *
     28  *                                                                                             *
     29  *                  Last Update : July 10, 1996 [JLB]                                          *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   RandomStraw::Get -- Fetch random data.                                                    *
     34  *   RandomStraw::RandomStraw -- Constructor for the random straw class.                       *
     35  *   RandomStraw::Reset -- Reset the data to known initial state.                              *
     36  *   RandomStraw::Scramble_Seed -- Masks any coorelation between the seed bits.                *
     37  *   RandomStraw::Seed_Bit -- Add a random bit to the accumulated seed value.                  *
     38  *   RandomStraw::Seed_Bits_Needed -- Fetches the number of seed bits needed.                  *
     39  *   RandomStraw::Seed_Byte -- Submit 8 bits to the random number seed.                        *
     40  *   RandomStraw::Seed_Long -- Submit 32 bits to the random number seed.                       *
     41  *   RandomStraw::Seed_Short -- Submit 16 bits to the random number seed.                      *
     42  *   RandomStraw::~RandomStraw -- Destructor for random straw class.                           *
     43  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     44 
     45 #include	<limits.h>
     46 #include	<string.h>
     47 #include	"rndstraw.h"
     48 #include	"sha.h"
     49 
     50 
     51 /***********************************************************************************************
     52  * RandomStraw::RandomStraw -- Constructor for the random straw class.                         *
     53  *                                                                                             *
     54  *    This will initialize the random straw into a known state. The initial state is useless   *
     55  *    for cryptographic purposes. It must be seeded before it should be used.                  *
     56  *                                                                                             *
     57  * INPUT:   none                                                                               *
     58  *                                                                                             *
     59  * OUTPUT:  none                                                                               *
     60  *                                                                                             *
     61  * WARNINGS:   none                                                                            *
     62  *                                                                                             *
     63  * HISTORY:                                                                                    *
     64  *   07/10/1996 JLB : Created.                                                                 *
     65  *=============================================================================================*/
     66 RandomStraw::RandomStraw(void) :
     67 	SeedBits(0),
     68 	Current(0)
     69 {
     70 	Reset();
     71 }
     72 
     73 
     74 /***********************************************************************************************
     75  * RandomStraw::~RandomStraw -- Destructor for random straw class.                             *
     76  *                                                                                             *
     77  *    This destructor will clear out the seed data so that there won't be any sensitive        *
     78  *    information left over in the memory this object occupied.                                *
     79  *                                                                                             *
     80  * INPUT:   none                                                                               *
     81  *                                                                                             *
     82  * OUTPUT:  none                                                                               *
     83  *                                                                                             *
     84  * WARNINGS:   none                                                                            *
     85  *                                                                                             *
     86  * HISTORY:                                                                                    *
     87  *   07/10/1996 JLB : Created.                                                                 *
     88  *=============================================================================================*/
     89 RandomStraw::~RandomStraw(void)
     90 {
     91 	Reset();
     92 }
     93 
     94 
     95 /***********************************************************************************************
     96  * RandomStraw::Reset -- Reset the data to known initial state.                                *
     97  *                                                                                             *
     98  *    This routine is functionally equivalent to performing an placement new on the object. It *
     99  *    clears out all the seed data.                                                            *
    100  *                                                                                             *
    101  * INPUT:   none                                                                               *
    102  *                                                                                             *
    103  * OUTPUT:  none                                                                               *
    104  *                                                                                             *
    105  * WARNINGS:   You must reseed it before fetching random numbers.                              *
    106  *                                                                                             *
    107  * HISTORY:                                                                                    *
    108  *   07/10/1996 JLB : Created.                                                                 *
    109  *=============================================================================================*/
    110 void RandomStraw::Reset(void)
    111 {
    112 	SeedBits = 0;
    113 	Current = 0;
    114 	memset(Random, '\0', sizeof(Random));
    115 }
    116 
    117 
    118 /***********************************************************************************************
    119  * RandomStraw::Seed_Bits_Needed -- Fetches the number of seed bits needed.                    *
    120  *                                                                                             *
    121  *    This routine is used when seeding the random straw. Keep feeding random bits to this     *
    122  *    class until the Seed_Bits_Needed value returns zero. Random bits should be gathered from *
    123  *    sources external to the immediate program. Examples would be the system clock (good for  *
    124  *    a few bits), the delay between player keystrokes (good for a few bits per keystroke),    *
    125  *    etc. When gathering random bits from integers, use the low order bits (since they        *
    126  *    characteristically are less predictable and more 'random' than the others).              *
    127  *                                                                                             *
    128  * INPUT:   none                                                                               *
    129  *                                                                                             *
    130  * OUTPUT:  Returns with the number of bits required in order to fully seed this random        *
    131  *          number generator.                                                                  *
    132  *                                                                                             *
    133  * WARNINGS:   Even if this routine returns zero, you are still allowed and encouraged to feed *
    134  *             more random bits when the opportunity arrises.                                  *
    135  *                                                                                             *
    136  * HISTORY:                                                                                    *
    137  *   07/10/1996 JLB : Created.                                                                 *
    138  *=============================================================================================*/
    139 int RandomStraw::Seed_Bits_Needed(void) const
    140 {
    141 	const int total = sizeof(Random) * CHAR_BIT;
    142 	if (SeedBits < total) {
    143 		return(total - SeedBits);
    144 	}
    145 	return(0);
    146 }
    147 
    148 
    149 /***********************************************************************************************
    150  * RandomStraw::Seed_Bit -- Add a random bit to the accumulated seed value.                    *
    151  *                                                                                             *
    152  *    This routine should be called to feed a single random bit to the random straw object.    *
    153  *    You must feed as many bits as requested by the Seed_Bits_Needed() function. Submitting   *
    154  *    additional bits is not only allowed, but encouraged.                                     *
    155  *                                                                                             *
    156  * INPUT:   seed  -- The bit (lowest order bit) to feed to the random number seed.             *
    157  *                                                                                             *
    158  * OUTPUT:  none                                                                               *
    159  *                                                                                             *
    160  * WARNINGS:   none                                                                            *
    161  *                                                                                             *
    162  * HISTORY:                                                                                    *
    163  *   07/10/1996 JLB : Created.                                                                 *
    164  *=============================================================================================*/
    165 void RandomStraw::Seed_Bit(int seed)
    166 {
    167 	char * ptr = ((char *)&Random[0]) + ((SeedBits / CHAR_BIT) % sizeof(Random));
    168 	char frac = (char)(1 << (SeedBits & (CHAR_BIT-1)));
    169 
    170 	if (seed & 0x01) {
    171 		*ptr ^= frac;
    172 	}
    173 	SeedBits++;
    174 
    175 	if (SeedBits == (sizeof(Random) * CHAR_BIT)) {
    176 		Scramble_Seed();
    177 	}
    178 }
    179 
    180 
    181 /***********************************************************************************************
    182  * RandomStraw::Seed_Byte -- Submit 8 bits to the random number seed.                          *
    183  *                                                                                             *
    184  *    This will submit 8 bits (as specified) to the random number seed.                        *
    185  *                                                                                             *
    186  * INPUT:   seed  -- The seed bits to submit.                                                  *
    187  *                                                                                             *
    188  * OUTPUT:  none                                                                               *
    189  *                                                                                             *
    190  * WARNINGS:   none                                                                            *
    191  *                                                                                             *
    192  * HISTORY:                                                                                    *
    193  *   07/10/1996 JLB : Created.                                                                 *
    194  *=============================================================================================*/
    195 void RandomStraw::Seed_Byte(char seed)
    196 {
    197 	for (int index = 0; index < CHAR_BIT; index++) {
    198 		Seed_Bit(seed);
    199 		seed >>= 1;
    200 	}
    201 }
    202 
    203 
    204 /***********************************************************************************************
    205  * RandomStraw::Seed_Short -- Submit 16 bits to the random number seed.                        *
    206  *                                                                                             *
    207  *    This will submit 16 bits to the accumulated seed.                                        *
    208  *                                                                                             *
    209  * INPUT:   seed  -- The 16 bits to submit to the seed.                                        *
    210  *                                                                                             *
    211  * OUTPUT:  none                                                                               *
    212  *                                                                                             *
    213  * WARNINGS:   none                                                                            *
    214  *                                                                                             *
    215  * HISTORY:                                                                                    *
    216  *   07/10/1996 JLB : Created.                                                                 *
    217  *=============================================================================================*/
    218 void RandomStraw::Seed_Short(short seed)
    219 {
    220 	for (int index = 0; index < (sizeof(seed)*CHAR_BIT); index++) {
    221 		Seed_Bit(seed);
    222 		seed >>= 1;
    223 	}
    224 }
    225 
    226 
    227 /***********************************************************************************************
    228  * RandomStraw::Seed_Long -- Submit 32 bits to the random number seed.                         *
    229  *                                                                                             *
    230  *    This will submit a full 32 bits to the accumulated seed value.                           *
    231  *                                                                                             *
    232  * INPUT:   seed  -- The 32 bits to submit.                                                    *
    233  *                                                                                             *
    234  * OUTPUT:  none                                                                               *
    235  *                                                                                             *
    236  * WARNINGS:   none                                                                            *
    237  *                                                                                             *
    238  * HISTORY:                                                                                    *
    239  *   07/10/1996 JLB : Created.                                                                 *
    240  *=============================================================================================*/
    241 void RandomStraw::Seed_Long(long seed)
    242 {
    243 	for (int index = 0; index < (sizeof(seed)*CHAR_BIT); index++) {
    244 		Seed_Bit(seed);
    245 		seed >>= 1;
    246 	}
    247 }
    248 
    249 
    250 /***********************************************************************************************
    251  * RandomStraw::Scramble_Seed -- Masks any coorelation between the seed bits.                  *
    252  *                                                                                             *
    253  *    This routine is called when a full set of seed bits has been accumulated. It will take   *
    254  *    the existing seed and scramble the bits. An effective way of doing this is to use the    *
    255  *    Secure Hash Algorithm. It is necessary to have this routine because there might be       *
    256  *    some coorelation in the seed bits. Even more important is that this routine will result  *
    257  *    in every bit of the seed having a scrambling effect on every other bit.                  *
    258  *                                                                                             *
    259  * INPUT:   none                                                                               *
    260  *                                                                                             *
    261  * OUTPUT:  none                                                                               *
    262  *                                                                                             *
    263  * WARNINGS:   none                                                                            *
    264  *                                                                                             *
    265  * HISTORY:                                                                                    *
    266  *   07/10/1996 JLB : Created.                                                                 *
    267  *=============================================================================================*/
    268 void RandomStraw::Scramble_Seed(void)
    269 {
    270 	SHAEngine sha;
    271 
    272 	for (int index = 0; index < sizeof(Random); index++) {
    273 		char digest[20];
    274 
    275 		sha.Hash(&Random[0], sizeof(Random));
    276 		sha.Result(digest);
    277 
    278 		int tocopy = sizeof(digest) < (sizeof(Random)-index) ? sizeof(digest) : (sizeof(Random)-index);
    279 		memmove(((char *)&Random[0]) + index, digest, tocopy);
    280 	}
    281 }
    282 
    283 
    284 /***********************************************************************************************
    285  * RandomStraw::Get -- Fetch random data.                                                      *
    286  *                                                                                             *
    287  *    This routine will fetch random data and store it into the buffer specified.              *
    288  *                                                                                             *
    289  * INPUT:   source   -- Pointer to the buffer to fill with random data.                        *
    290  *                                                                                             *
    291  *          length   -- The number of bytes to store into the buffer.                          *
    292  *                                                                                             *
    293  * OUTPUT:  Returns with the actual number of bytes stored into the buffer. This will always   *
    294  *          be the number of bytes requested since random numbers are unexhaustible.           *
    295  *                                                                                             *
    296  * WARNINGS:   none                                                                            *
    297  *                                                                                             *
    298  * HISTORY:                                                                                    *
    299  *   07/04/1996 JLB : Created.                                                                 *
    300  *   07/10/1996 JLB : Revamped to make cryptographically secure.                               *
    301  *=============================================================================================*/
    302 int RandomStraw::Get(void * source, int slen)
    303 {
    304 	if (source == NULL || slen < 1) {
    305 		return(Straw::Get(source, slen));
    306 	}
    307 
    308 	int total = 0;
    309 	while (slen > 0) {
    310 		*(char *)source = (char)Random[Current++];
    311 		Current = Current % (sizeof(Random) / sizeof(Random[0]));
    312 		source = (char*)source + sizeof(char);
    313 		slen--;
    314 		total++;
    315 	}
    316 	return(total);
    317 }