Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
pkstraw.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** 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 ***
21 ***********************************************************************************************
22 * *
23 * Project Name : Command & Conquer *
24 * *
25 * $Archive:: /Commando/Library/PKSTRAW.CPP $*
26 * *
27 * $Author:: Greg_h $*
28 * *
29 * $Modtime:: 7/22/97 11:37a $*
30 * *
31 * $Revision:: 1 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * PKStraw::Encrypted_Key_Length -- Fetch the encrypted key length. *
36 * PKStraw::Get -- Fetch data and process it accordingly. *
37 * PKStraw::Get_From -- Chains one straw to another. *
38 * PKStraw::Key -- Assign a key to the cipher process straw. *
39 * PKStraw::PKStraw -- Initialize the public key straw object. *
40 * PKStraw::Plain_Key_Length -- Returns the number of bytes to encrypt key. *
41 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
42
43#include "always.h"
44#include "blwstraw.h"
45#include "pkstraw.h"
46#include "rndstraw.h"
47#include <string.h>
48
49
50/***********************************************************************************************
51 * PKStraw::PKStraw -- Initialize the public key straw object. *
52 * *
53 * This constructs the public key straw object. The operation to perform (encrypt or *
54 * decrypt) as well as a random number generator must be provided. *
55 * *
56 * INPUT: control -- What operation to perform on the data. Pass in either ENCRYPT or *
57 * DECRYPT. *
58 * *
59 * rnd -- Reference to a random number straw that is used internally to *
60 * generate the sub-key. The final strength of the cipher depends on *
61 * quality of this random number generator. *
62 * *
63 * OUTPUT: none *
64 * *
65 * WARNINGS: none *
66 * *
67 * HISTORY: *
68 * 07/11/1996 JLB : Created. *
69 *=============================================================================================*/
71 IsGettingKey(true),
72 Rand(rnd),
73 BF((control == ENCRYPT) ? BlowStraw::ENCRYPT : BlowStraw::DECRYPT),
74 Control(control),
75 CipherKey(NULL),
76 Counter(0),
77 BytesLeft(0)
78{
80}
81
82
83/***********************************************************************************************
84 * PKStraw::Get_From -- Chains one straw to another. *
85 * *
86 * This routine handles the special case of this straw object in that there is an *
87 * embedded blowfish straw segment. It must be chained on correctly. *
88 * *
89 * INPUT: straw -- Pointer to the straw segment that this segment is to receive data from. *
90 * *
91 * OUTPUT: none *
92 * *
93 * WARNINGS: none *
94 * *
95 * HISTORY: *
96 * 07/11/1996 JLB : Created. *
97 *=============================================================================================*/
99{
100 if (BF.ChainTo != straw) {
101 if (straw != NULL && straw->ChainFrom != NULL) {
102 straw->ChainFrom->Get_From(NULL);
103 straw->ChainFrom = NULL;
104 }
105
106 if (BF.ChainTo != NULL) {
107 BF.ChainTo->ChainFrom = NULL;
108 }
109
110 BF.ChainTo = straw;
111 BF.ChainFrom = this;
112 ChainTo = &BF;
113 if (BF.ChainTo != NULL) {
114 BF.ChainTo->ChainFrom = this;
115 }
116 }
117}
118
119
120
121/***********************************************************************************************
122 * PKStraw::Key -- Assign a key to the cipher process straw. *
123 * *
124 * This routine will assign the key (or NULL if the current key is to be removed) to the *
125 * cipher stream process. When a key has been assigned, encryption or decryption will *
126 * take place. In the absence (NULL key pointer) of a key, the data passes through *
127 * unchanged. *
128 * *
129 * INPUT: key -- Pointer to the key to assign to the stream. If the key pointer is NULL, *
130 * then this causes the cipher stream to stop processing the data and will *
131 * pass the data through unchanged. *
132 * *
133 * OUTPUT: none *
134 * *
135 * WARNINGS: Be sure that the key passed to this routine is the opposite key to that used *
136 * to process the stream originally (when decrypting). *
137 * *
138 * HISTORY: *
139 * 07/08/1996 JLB : Created. *
140 *=============================================================================================*/
141void PKStraw::Key(PKey const * key)
142{
143 CipherKey = key;
144 if (key != NULL) {
145 IsGettingKey = true;
146 }
147 Counter = 0;
148 BytesLeft = 0;
149}
150
151
152/***********************************************************************************************
153 * PKStraw::Get -- Fetch data and process it accordingly. *
154 * *
155 * This routine will fetch the number of bytes requested. If a valid key has been assigned *
156 * to this stream, then the data will be processed as it passes through. *
157 * *
158 * INPUT: source -- Pointer to the buffer that will hold the requested data. *
159 * *
160 * length -- The number of data bytes requested. *
161 * *
162 * OUTPUT: Returns with the actual number of data bytes stored to the destination buffer. If *
163 * this number is less than that requested, then it indicates that the data source *
164 * has been exhausted. *
165 * *
166 * WARNINGS: none *
167 * *
168 * HISTORY: *
169 * 07/08/1996 JLB : Created. *
170 *=============================================================================================*/
171int PKStraw::Get(void * source, int length)
172{
173 /*
174 ** If the parameters seem invalid, then pass the request on so that someone
175 ** else can deal with it.
176 */
177 if (source == NULL || length < 1 || CipherKey == NULL) {
178 return(Straw::Get(source, length));
179 }
180
181 int total = 0;
182
183 /*
184 ** The first part of the data flow must process the special key. After the special
185 ** key has been processed, the data flows through this straw without direct
186 ** modification (the blowfish straw will process the data).
187 */
188 if (IsGettingKey) {
189
190 if (Control == DECRYPT) {
191
192 /*
193 ** Retrieve the pk encrypted blowfish key block.
194 */
195 char cbuffer[MAX_KEY_BLOCK_SIZE];
196 int got = Straw::Get(cbuffer, Encrypted_Key_Length());
197
198 /*
199 ** If the entire key block could not be retrieved, then this indicates
200 ** a major data flow error -- just return with no action performed.
201 */
202 if (got != Encrypted_Key_Length()) return(0);
203
204 /*
205 ** Decrypt the blowfish key and then activate the blowfish straw
206 ** with that key.
207 */
208 CipherKey->Decrypt(cbuffer, got, Buffer);
209 BF.Key(Buffer, BLOWFISH_KEY_SIZE);
210
211 } else {
212
213 /*
214 ** Generate the blowfish key by using random numbers.
215 */
216 char buffer[MAX_KEY_BLOCK_SIZE];
217 memset(buffer, '\0', sizeof(buffer));
218 Rand.Get(buffer, BLOWFISH_KEY_SIZE);
219
220 /*
221 ** Encrypt the blowfish key (along with any necessary pad bytes).
222 */
223 Counter = BytesLeft = CipherKey->Encrypt(buffer, Plain_Key_Length(), Buffer);
224 BF.Key(buffer, BLOWFISH_KEY_SIZE);
225 }
226
227 /*
228 ** The first phase of getting the special key has been accomplished. Now, all
229 ** subsequent data is passed (unmodified) though this straw segment. The blowfish
230 ** straw takes over the compression/decompression from this point forward.
231 */
232 IsGettingKey = false;
233 }
234
235 /*
236 ** If there are any pending bytes in the buffer, then pass
237 ** these on first. The only time this should be is when the blowfish
238 ** key has first been generated.
239 */
240 if (BytesLeft > 0) {
241 int tocopy = (length < BytesLeft) ? length : BytesLeft;
242 memmove(source, &Buffer[Counter-BytesLeft], tocopy);
243 source = (char *)source + tocopy;
244 BytesLeft -= tocopy;
245 length -= tocopy;
246 total += tocopy;
247 }
248
249 /*
250 ** Any requested bytes that haven't been satisfied are copied over now by
251 ** drawing the data through the blowfish engine. The blowfish engine happens
252 ** to be linked to the chain so a normal Get() operation is sufficient.
253 */
254 total += Straw::Get(source, length);
255
256 return(total);
257}
258
259
260/***********************************************************************************************
261 * PKStraw::Encrypted_Key_Length -- Fetch the encrypted key length. *
262 * *
263 * This returns the total number of bytes (after encryption) that the blowfish key will *
264 * consume. It should be possible to get a block of this size, then pass it to the *
265 * public key decrypter and the result will be the full blowfish key. *
266 * *
267 * INPUT: none *
268 * *
269 * OUTPUT: Returns with the number of bytes that the encrypted blowfish key required. *
270 * *
271 * WARNINGS: none *
272 * *
273 * HISTORY: *
274 * 07/11/1996 JLB : Created. *
275 *=============================================================================================*/
276int PKStraw::Encrypted_Key_Length(void) const
277{
278 if (CipherKey == NULL) return(0);
279 return(CipherKey->Block_Count(BLOWFISH_KEY_SIZE) * CipherKey->Crypt_Block_Size());
280}
281
282
283/***********************************************************************************************
284 * PKStraw::Plain_Key_Length -- Returns the number of bytes to encrypt key. *
285 * *
286 * This is the number of plain (unencrypted) bytes that the blowfish key will take up. This *
287 * is actually the number of plain blocks minimum that can contain the full blowfish *
288 * key. The public key cryptography system encrypts in whole blocks only. *
289 * *
290 * INPUT: none *
291 * *
292 * OUTPUT: Returns with the total number of bytes that will contain the full blowfish key *
293 * and still be an even block size for the public key cryptography process. *
294 * *
295 * WARNINGS: This value is probably be larger than the actual blowfish key length. *
296 * *
297 * HISTORY: *
298 * 07/11/1996 JLB : Created. *
299 *=============================================================================================*/
300int PKStraw::Plain_Key_Length(void) const
301{
302 if (CipherKey == NULL) return(0);
303 return(CipherKey->Block_Count(BLOWFISH_KEY_SIZE) * CipherKey->Plain_Block_Size());
304}
#define NULL
Definition BaseType.h:92
@ true
Definition bool.h:59
CryptControl
Definition pkstraw.h:48
@ DECRYPT
Definition pkstraw.h:50
@ ENCRYPT
Definition pkstraw.h:49
virtual void Get_From(Straw *straw)
Definition pkstraw.cpp:98
virtual int Get(void *source, int slen)
Definition pkstraw.cpp:171
PKStraw(CryptControl control, RandomStraw &rnd)
Definition pkstraw.cpp:70
void Key(PKey const *key)
Definition pkstraw.cpp:141
Definition PK.H:63
int Crypt_Block_Size(void) const
Definition PK.H:74
int Block_Count(int plaintext_length) const
Definition PK.H:75
virtual int Get(void *buffer, int slen)
Definition straw.cpp:132
Straw * ChainTo
Definition STRAW.H:63
Straw * ChainFrom
Definition STRAW.H:64
virtual void Get_From(Straw *pipe)
Definition straw.cpp:92
Straw(void)
Definition STRAW.H:53