CnC_Remastered_Collection

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

PK.CPP (21799B)


      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/PK.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 : PK.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  *   PKey::Decode_Exponent -- Decodes the exponent back into the key.                          *
     34  *   PKey::Decode_Modulus -- Decodes the modulus value back into the key.                      *
     35  *   PKey::Decrypt -- Decrypt supplied cyphertext into its original plaintext.                 *
     36  *   PKey::Encode_Exponent -- Encode the exponent portion of the key into a buffer.            *
     37  *   PKey::Encode_Modulus -- Encode the modulus portion of the key.                            *
     38  *   PKey::Encrypt -- Encrypt blocks of plaintext.                                             *
     39  *   PKey::Generate -- Generate a public and private key.                                      *
     40  *   PKey::PKey -- Construct a key using encoded strings.                                      *
     41  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     42 
     43 #include	"pk.h"
     44 #include	"rndstraw.h"
     45 
     46 
     47 /***********************************************************************************************
     48  * PKey::PKey -- Construct a key using encoded strings.                                        *
     49  *                                                                                             *
     50  *    This constructor will construct a key based on the encoded strings supplied.             *
     51  *                                                                                             *
     52  * INPUT:   exponent -- The encoded string for the exponent portion of the key.                *
     53  *                                                                                             *
     54  *          modulus  -- The encoded string for the modulus portion of the key.                 *
     55  *                                                                                             *
     56  * OUTPUT:  none                                                                               *
     57  *                                                                                             *
     58  * WARNINGS:   none                                                                            *
     59  *                                                                                             *
     60  * HISTORY:                                                                                    *
     61  *   07/08/1996 JLB : Created.                                                                 *
     62  *=============================================================================================*/
     63 PKey::PKey(void const * exponent, void const * modulus)
     64 {
     65 	Modulus.DERDecode((unsigned char *)modulus);
     66 	Exponent.DERDecode((unsigned char *)exponent);
     67 	BitPrecision = Modulus.BitCount()-1;
     68 }
     69 
     70 
     71 /***********************************************************************************************
     72  * PKey::Encode_Modulus -- Encode the modulus portion of the key.                              *
     73  *                                                                                             *
     74  *    This will store the modulus portion of the key into a buffer. The number of bytes        *
     75  *    stored into the buffer depends on the value of the key.                                  *
     76  *                                                                                             *
     77  * INPUT:   buffer   -- Pointer to the buffer that will hold the encoded modulus value.        *
     78  *                                                                                             *
     79  * OUTPUT:  Returns with the number of bytes stored to the buffer.                             *
     80  *                                                                                             *
     81  * WARNINGS:   Be sure that the buffer can hold the encoded bytes. This is normally around the *
     82  *             same size as the Crypt_Block_Size() (plus a byte or two).                       *
     83  *                                                                                             *
     84  * HISTORY:                                                                                    *
     85  *   07/08/1996 JLB : Created.                                                                 *
     86  *=============================================================================================*/
     87 int PKey::Encode_Modulus(void * buffer) const
     88 {
     89 	if (buffer == NULL) {
     90 		return(0);
     91 	}
     92 	return(Modulus.DEREncode((unsigned char *)buffer));
     93 }
     94 
     95 
     96 /***********************************************************************************************
     97  * PKey::Encode_Exponent -- Encode the exponent portion of the key into a buffer.              *
     98  *                                                                                             *
     99  *    This routine will encode the exponent portion of the key. This is only necessary for the *
    100  *    slow key since the fast key always has an exponent of 65537.                             *
    101  *                                                                                             *
    102  * INPUT:   buffer   -- Pointer to the buffer that will be filled with the encoded exponent.   *
    103  *                                                                                             *
    104  * OUTPUT:  Returns with the nuber of bytes stored into the buffer.                            *
    105  *                                                                                             *
    106  * WARNINGS:   Be sure the buffer is big enough to hold the encoded exponent. Usually this is  *
    107  *             about the same size as the Crypt_Block_Size (plus a byte or two).               *
    108  *                                                                                             *
    109  * HISTORY:                                                                                    *
    110  *   07/08/1996 JLB : Created.                                                                 *
    111  *=============================================================================================*/
    112 int PKey::Encode_Exponent(void * buffer) const
    113 {
    114 	if (buffer == NULL) {
    115 		return(0);
    116 	}
    117 	return(Exponent.DEREncode((unsigned char *)buffer));
    118 }
    119 
    120 
    121 /***********************************************************************************************
    122  * PKey::Decode_Modulus -- Decodes the modulus value back into the key.                        *
    123  *                                                                                             *
    124  *    This is the counterpart to the Encode_Modulus() function. It will initialize the         *
    125  *    modulus portion of the key with the encoded data supplied.                               *
    126  *                                                                                             *
    127  * INPUT:   buffer   -- Pointer to the buffer that holds the previously encoded modulus value. *
    128  *                                                                                             *
    129  * OUTPUT:  void                                                                               *
    130  *                                                                                             *
    131  * WARNINGS:   void                                                                            *
    132  *                                                                                             *
    133  * HISTORY:                                                                                    *
    134  *   07/08/1996 JLB : Created.                                                                 *
    135  *=============================================================================================*/
    136 void PKey::Decode_Modulus(void * buffer)
    137 {
    138 	Modulus.DERDecode((unsigned char *)buffer);
    139 	BitPrecision = Modulus.BitCount()-1;
    140 }
    141 
    142 
    143 /***********************************************************************************************
    144  * PKey::Decode_Exponent -- Decodes the exponent back into the key.                            *
    145  *                                                                                             *
    146  *    This is the counterpart to the Encode_Exponent function. It will decode a previously     *
    147  *    encoded exponent portion back into the key.                                              *
    148  *                                                                                             *
    149  * INPUT:   buffer   -- Pointer to the buffer that holds the encoded exponent value.           *
    150  *                                                                                             *
    151  * OUTPUT:  none                                                                               *
    152  *                                                                                             *
    153  * WARNINGS:   none                                                                            *
    154  *                                                                                             *
    155  * HISTORY:                                                                                    *
    156  *   07/08/1996 JLB : Created.                                                                 *
    157  *=============================================================================================*/
    158 void PKey::Decode_Exponent(void * buffer)
    159 {
    160 	Exponent.DERDecode((unsigned char *)buffer);
    161 }
    162 
    163 
    164 /***********************************************************************************************
    165  * PKey::Generate -- Generate a public and private key.                                        *
    166  *                                                                                             *
    167  *    Public key cryptography relies on having two paired keys. The key used to encrypt        *
    168  *    data must be decrypted by using the other key. Which key designated as the public or     *
    169  *    private key is arbitrary. However, one is faster than the other. Use the faster key for  *
    170  *    the more common operation.                                                               *
    171  *                                                                                             *
    172  * INPUT:   random   -- Reference to a source of random data.                                  *
    173  *                                                                                             *
    174  *          bits     -- The number of bits to use for key generation. Use a number greater     *
    175  *                      than 16 but less than 2048. The ideal bit size is one that is evenly   *
    176  *                      divisible by 8 and then add one. Practical numbers range from 65 to    *
    177  *                      1025 bits.                                                             *
    178  *                                                                                             *
    179  *          fastkey  -- Reference to the key that has fast encryption/decryption properties.   *
    180  *                                                                                             *
    181  *          slowkey  -- Reference to the mate key of the other.                                *
    182  *                                                                                             *
    183  * OUTPUT:  none                                                                               *
    184  *                                                                                             *
    185  * WARNINGS:   This routine can take a very long time. It can take MINUTES to generate a       *
    186  *             1024 bit key (even on a Pentium Pro 200Mghz machine).                           *
    187  *                                                                                             *
    188  * HISTORY:                                                                                    *
    189  *   07/05/1996 JLB : Created.                                                                 *
    190  *   07/10/1996 JLB : Must supply source of random data.                                       *
    191  *=============================================================================================*/
    192 void PKey::Generate(Straw & random, int bits, PKey & fastkey, PKey & slowkey)
    193 {
    194 	//PG_TO_FIX
    195 	fastkey;
    196 	slowkey;
    197 #if (0)
    198 	/*
    199 	**	Key generation consists of create a key pair and then testing the key
    200 	**	pair. If the test fails, then repeat the process. The test and repeat
    201 	**	method is required since the prime number generating process can't
    202 	**	guarantee the generation of a prime number -- it can only generate a
    203 	**	highly likely prime number.
    204 	*/
    205 	for (;;) {
    206 		/*
    207 		**	Generate the two random prime numbers. This is the longest
    208 		**	step.
    209 		*/
    210 		BigInt p = Generate_Prime(random, bits, &p);
    211 		BigInt q = Generate_Prime(random, bits, &q);
    212 
    213 		/*
    214 		**	The exponent factors are easy to calculate from the prime numbers.
    215 		*/
    216 		BigInt e = Fast_Exponent();
    217 		BigInt n = p * q;
    218 		BigInt pqmin = (p-(unsigned short)1)*(q-(unsigned short)1);
    219 		BigInt d = e.Inverse(pqmin);
    220 
    221 		/*
    222 		**	Store the data into the key objects. Notice that the modulus is the
    223 		**	same for both the fast and slow keys. Also notice that the exponent for
    224 		**	the fast key is ALWAYS 65537. Given this, it is possible to economize the
    225 		**	fast key into being just the modulus and the slow key to being just the
    226 		**	exponent (presuming the slow key also has access to the fast key so that
    227 		**	it can get the modulus).
    228 		*/
    229 		fastkey.Exponent = e;
    230 		fastkey.Modulus = n;
    231 		fastkey.BitPrecision = n.BitCount()-1;
    232 
    233 		slowkey.Exponent = d;
    234 		slowkey.Modulus = n;
    235 		slowkey.BitPrecision = fastkey.BitPrecision;
    236 
    237 		/*
    238 		**	Test the keys by encrypting a block of random bytes. If it decrypts
    239 		**	correctly, then a valid key pair has been generated -- bail.
    240 		*/
    241 		char before[256];
    242 		char after[256];
    243 
    244 		for (int index = 0; index < fastkey.Plain_Block_Size(); index++) {
    245 			before[index] = (char)rand();
    246 		}
    247 		fastkey.Encrypt(before, fastkey.Plain_Block_Size(), after);
    248 		slowkey.Decrypt(after, slowkey.Crypt_Block_Size(), after);
    249 
    250 		/*
    251 		**	Compare the pre and post processing buffer. A match indicates
    252 		**	a valid key pair.
    253 		*/
    254 		if (memcmp(before, after, fastkey.Plain_Block_Size()) == 0) break;
    255 	}
    256 #endif
    257 }
    258 
    259 
    260 /***********************************************************************************************
    261  * PKey::Encrypt -- Encrypt blocks of plaintext.                                               *
    262  *                                                                                             *
    263  *    This routine will encrypt the supplied plaintext into cyphertext by processing the input *
    264  *    in block. The source is processed in whole blocks. Partial blocks are not supported by   *
    265  *    public key cryptography.                                                                 *
    266  *                                                                                             *
    267  * INPUT:   source   -- Pointer to the source plaintext that will be encrypted.                *
    268  *                                                                                             *
    269  *          length   -- The length of the plaintext to encrypt.                                *
    270  *                                                                                             *
    271  *          dest     -- Pointer to the buffer that will hold the encrypted data.               *
    272  *                                                                                             *
    273  * OUTPUT:  Returns with the number of cypher text bytes placed into the destination buffer.   *
    274  *                                                                                             *
    275  * WARNINGS:   Be sure that the destination buffer is big enough to hold the output.           *
    276  *                                                                                             *
    277  * HISTORY:                                                                                    *
    278  *   07/05/1996 JLB : Created.                                                                 *
    279  *=============================================================================================*/
    280 int PKey::Encrypt(void const * source, int slen, void * dest) const
    281 {
    282 	int total = 0;
    283 
    284 	/*
    285 	**	Encrypt the source data in full blocks. Partial blocks are not processed and are not
    286 	**	copied to the destination buffer.
    287 	*/
    288 	while (slen >= Plain_Block_Size()) {
    289 
    290 		/*
    291 		**	Perform the encryption of the block.
    292 		*/
    293 		BigInt temp = 0;
    294 		memmove(&temp, source, Plain_Block_Size());
    295 		temp = temp.exp_b_mod_c(Exponent, Modulus);
    296 
    297 		/*
    298 		**	Move the cypher block to the destination.
    299 		*/
    300 		memmove(dest, &temp, Crypt_Block_Size());
    301 		slen -= Plain_Block_Size();
    302 		source = (char *)source + Plain_Block_Size();
    303 		dest = (char *)dest + Crypt_Block_Size();
    304 		total += Crypt_Block_Size();
    305 	}
    306 
    307 	return(total);
    308 }
    309 
    310 
    311 /***********************************************************************************************
    312  * PKey::Decrypt -- Decrypt supplied cyphertext into its original plaintext.                   *
    313  *                                                                                             *
    314  *    This routine will process the supplied cyphertext by breaking it up into blocks and      *
    315  *    then decrypting each block in turn. The block size is dependant upon the key. By NOT     *
    316  *    embedding this information into the cypher data, it makes the encryption more secure.    *
    317  *                                                                                             *
    318  * INPUT:   source   -- Pointer to the cypher text to be decrypted.                            *
    319  *                                                                                             *
    320  *          length   -- The number of cypher text bytes supplied to this routine.              *
    321  *                                                                                             *
    322  *          dest     -- Pointer to the buffer to hold the plaintext.                           *
    323  *                                                                                             *
    324  * OUTPUT:  Returns with the number of plaintext bytes output to the destination buffer.       *
    325  *                                                                                             *
    326  * WARNINGS:   Only whole blocks are processed. If the source has any partial block sized      *
    327  *             data, then it will be left unprocessed.                                         *
    328  *                                                                                             *
    329  * HISTORY:                                                                                    *
    330  *   07/05/1996 JLB : Created.                                                                 *
    331  *=============================================================================================*/
    332 int PKey::Decrypt(void const * source, int slen, void * dest) const
    333 {
    334 	int total = 0;
    335 	BigInt temp;
    336 
    337 	/*
    338 	**	Decrypt the source data in full blocks. Partial blocks are not processed in any way.
    339 	*/
    340 	while (slen >= Crypt_Block_Size()) {
    341 
    342 		/*
    343 		**	Perform the encryption.
    344 		*/
    345 		temp = 0;
    346 		memmove(&temp, source, Crypt_Block_Size());
    347 		temp = temp.exp_b_mod_c(Exponent, Modulus);
    348 
    349 		/*
    350 		**	Move the cypher block to the destination.
    351 		*/
    352 		memmove(dest, &temp, Plain_Block_Size());
    353 		slen -= Crypt_Block_Size();
    354 		source = (char *)source + Crypt_Block_Size();
    355 		dest = (char *)dest + Plain_Block_Size();
    356 		total += Plain_Block_Size();
    357 	}
    358 
    359 	return(total);
    360 }