| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- /*
- ** Command & Conquer Red Alert(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /* $Header: /CounterStrike/PKSTRAW.CPP 1 3/03/97 10:25a Joe_bostic $ */
- /***********************************************************************************************
- *** 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 ***
- ***********************************************************************************************
- * *
- * Project Name : Command & Conquer *
- * *
- * File Name : PKSTRAW.CPP *
- * *
- * Programmer : Joe L. Bostic *
- * *
- * Start Date : 07/08/96 *
- * *
- * Last Update : July 11, 1996 [JLB] *
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * PKStraw::Encrypted_Key_Length -- Fetch the encrypted key length. *
- * PKStraw::Get -- Fetch data and process it accordingly. *
- * PKStraw::Get_From -- Chains one straw to another. *
- * PKStraw::Key -- Assign a key to the cipher process straw. *
- * PKStraw::PKStraw -- Initialize the public key straw object. *
- * PKStraw::Plain_Key_Length -- Returns the number of bytes to encrypt key. *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include "pkstraw.h"
- #include "rndstraw.h"
- #include "blwstraw.h"
- /***********************************************************************************************
- * PKStraw::PKStraw -- Initialize the public key straw object. *
- * *
- * This constructs the public key straw object. The operation to perform (encrypt or *
- * decrypt) as well as a random number generator must be provided. *
- * *
- * INPUT: control -- What operation to perform on the data. Pass in either ENCRYPT or *
- * DECRYPT. *
- * *
- * rnd -- Reference to a random number straw that is used internally to *
- * generate the sub-key. The final strength of the cipher depends on *
- * quality of this random number generator. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/11/1996 JLB : Created. *
- *=============================================================================================*/
- PKStraw::PKStraw(CryptControl control, RandomStraw & rnd) :
- IsGettingKey(true),
- Rand(rnd),
- BF((control == ENCRYPT) ? BlowStraw::ENCRYPT : BlowStraw::DECRYPT),
- Control(control),
- CipherKey(NULL),
- Counter(0),
- BytesLeft(0)
- {
- Straw::Get_From(BF);
- }
- /***********************************************************************************************
- * PKStraw::Get_From -- Chains one straw to another. *
- * *
- * This routine handles the special case of this straw object in that there is an *
- * embedded blowfish straw segment. It must be chained on correctly. *
- * *
- * INPUT: straw -- Pointer to the straw segment that this segment is to receive data from. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/11/1996 JLB : Created. *
- *=============================================================================================*/
- void PKStraw::Get_From(Straw * straw)
- {
- if (BF.ChainTo != straw) {
- if (straw != NULL && straw->ChainFrom != NULL) {
- straw->ChainFrom->Get_From(NULL);
- straw->ChainFrom = NULL;
- }
- if (BF.ChainTo != NULL) {
- BF.ChainTo->ChainFrom = NULL;
- }
- BF.ChainTo = straw;
- BF.ChainFrom = this;
- ChainTo = &BF;
- if (BF.ChainTo != NULL) {
- BF.ChainTo->ChainFrom = this;
- }
- }
- }
- /***********************************************************************************************
- * PKStraw::Key -- Assign a key to the cipher process straw. *
- * *
- * This routine will assign the key (or NULL if the current key is to be removed) to the *
- * cipher stream process. When a key has been assigned, encryption or decryption will *
- * take place. In the absence (NULL key pointer) of a key, the data passes through *
- * unchanged. *
- * *
- * INPUT: key -- Pointer to the key to assign to the stream. If the key pointer is NULL, *
- * then this causes the cipher stream to stop processing the data and will *
- * pass the data through unchanged. *
- * *
- * OUTPUT: none *
- * *
- * WARNINGS: Be sure that the key passed to this routine is the opposite key to that used *
- * to process the stream originally (when decrypting). *
- * *
- * HISTORY: *
- * 07/08/1996 JLB : Created. *
- *=============================================================================================*/
- void PKStraw::Key(PKey const * key)
- {
- CipherKey = key;
- if (key != NULL) {
- IsGettingKey = true;
- }
- Counter = 0;
- BytesLeft = 0;
- }
- /***********************************************************************************************
- * PKStraw::Get -- Fetch data and process it accordingly. *
- * *
- * This routine will fetch the number of bytes requested. If a valid key has been assigned *
- * to this stream, then the data will be processed as it passes through. *
- * *
- * INPUT: source -- Pointer to the buffer that will hold the requested data. *
- * *
- * length -- The number of data bytes requested. *
- * *
- * OUTPUT: Returns with the actual number of data bytes stored to the destination buffer. If *
- * this number is less than that requested, then it indicates that the data source *
- * has been exhausted. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/08/1996 JLB : Created. *
- *=============================================================================================*/
- int PKStraw::Get(void * source, int length)
- {
- /*
- ** If the parameters seem invalid, then pass the request on so that someone
- ** else can deal with it.
- */
- if (source == NULL || length < 1 || CipherKey == NULL) {
- return(Straw::Get(source, length));
- }
- int total = 0;
- /*
- ** The first part of the data flow must process the special key. After the special
- ** key has been processed, the data flows through this straw without direct
- ** modification (the blowfish straw will process the data).
- */
- if (IsGettingKey) {
- if (Control == DECRYPT) {
- /*
- ** Retrieve the pk encrypted blowfish key block.
- */
- char cbuffer[MAX_KEY_BLOCK_SIZE];
- int got = Straw::Get(cbuffer, Encrypted_Key_Length());
- /*
- ** If the entire key block could not be retrieved, then this indicates
- ** a major data flow error -- just return with no action performed.
- */
- if (got != Encrypted_Key_Length()) return(0);
- /*
- ** Decrypt the blowfish key and then activate the blowfish straw
- ** with that key.
- */
- CipherKey->Decrypt(cbuffer, got, Buffer);
- BF.Key(Buffer, BLOWFISH_KEY_SIZE);
- } else {
- /*
- ** Generate the blowfish key by using random numbers.
- */
- char buffer[MAX_KEY_BLOCK_SIZE];
- memset(buffer, '\0', sizeof(buffer));
- Rand.Get(buffer, BLOWFISH_KEY_SIZE);
- /*
- ** Encrypt the blowfish key (along with any necessary pad bytes).
- */
- Counter = BytesLeft = CipherKey->Encrypt(buffer, Plain_Key_Length(), Buffer);
- BF.Key(buffer, BLOWFISH_KEY_SIZE);
- }
- /*
- ** The first phase of getting the special key has been accomplished. Now, all
- ** subsequent data is passed (unmodified) though this straw segment. The blowfish
- ** straw takes over the compression/decompression from this point forward.
- */
- IsGettingKey = false;
- }
- /*
- ** If there are any pending bytes in the buffer, then pass
- ** these on first. The only time this should be is when the blowfish
- ** key has first been generated.
- */
- if (BytesLeft > 0) {
- int tocopy = (length < BytesLeft) ? length : BytesLeft;
- memmove(source, &Buffer[Counter-BytesLeft], tocopy);
- source = (char *)source + tocopy;
- BytesLeft -= tocopy;
- length -= tocopy;
- total += tocopy;
- }
- /*
- ** Any requested bytes that haven't been satisfied are copied over now by
- ** drawing the data through the blowfish engine. The blowfish engine happens
- ** to be linked to the chain so a normal Get() operation is sufficient.
- */
- total += Straw::Get(source, length);
- return(total);
- }
- /***********************************************************************************************
- * PKStraw::Encrypted_Key_Length -- Fetch the encrypted key length. *
- * *
- * This returns the total number of bytes (after encryption) that the blowfish key will *
- * consume. It should be possible to get a block of this size, then pass it to the *
- * public key decrypter and the result will be the full blowfish key. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: Returns with the number of bytes that the encrypted blowfish key required. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 07/11/1996 JLB : Created. *
- *=============================================================================================*/
- int PKStraw::Encrypted_Key_Length(void) const
- {
- if (CipherKey == NULL) return(0);
- return(CipherKey->Block_Count(BLOWFISH_KEY_SIZE) * CipherKey->Crypt_Block_Size());
- }
- /***********************************************************************************************
- * PKStraw::Plain_Key_Length -- Returns the number of bytes to encrypt key. *
- * *
- * This is the number of plain (unencrypted) bytes that the blowfish key will take up. This *
- * is actually the number of plain blocks minimum that can contain the full blowfish *
- * key. The public key cryptography system encrypts in whole blocks only. *
- * *
- * INPUT: none *
- * *
- * OUTPUT: Returns with the total number of bytes that will contain the full blowfish key *
- * and still be an even block size for the public key cryptography process. *
- * *
- * WARNINGS: This value is probably be larger than the actual blowfish key length. *
- * *
- * HISTORY: *
- * 07/11/1996 JLB : Created. *
- *=============================================================================================*/
- int PKStraw::Plain_Key_Length(void) const
- {
- if (CipherKey == NULL) return(0);
- return(CipherKey->Block_Count(BLOWFISH_KEY_SIZE) * CipherKey->Plain_Block_Size());
- }
|