Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
pkpipe.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/PKPIPE.CPP $*
26 * *
27 * $Author:: Greg_h $*
28 * *
29 * $Modtime:: 7/22/97 11:37a $*
30 * *
31 * $Revision:: 1 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * PKPipe::Encrypted_Key_Length -- Fetch the encrypted key length. *
36 * PKPipe::Key -- Submit a key to enable processing of data flow. *
37 * PKPipe::PKPipe -- Constructor for the public key pipe object. *
38 * PKPipe::Plain_Key_Length -- Returns the number of bytes to encrypt key. *
39 * PKPipe::Put -- Submit data to the pipe for processing. *
40 * PKPipe::Put_To -- Chains one pipe to another. *
41 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
42
43
44#include "always.h"
45#include "pkpipe.h"
46#include <string.h>
47
48
49/***********************************************************************************************
50 * PKPipe::PKPipe -- Constructor for the public key pipe object. *
51 * *
52 * This will construct the public key pipe object. *
53 * *
54 * INPUT: control -- The method used to process the data flow (encrypt or decrypt). *
55 * *
56 * rnd -- Reference to a random number generate used to create the internal *
57 * blowfish key. *
58 * *
59 * OUTPUT: none *
60 * *
61 * WARNINGS: none *
62 * *
63 * HISTORY: *
64 * 07/11/1996 JLB : Created. *
65 *=============================================================================================*/
67 IsGettingKey(true),
68 Rand(rnd),
69 BF((control == ENCRYPT) ? BlowPipe::ENCRYPT : BlowPipe::DECRYPT),
70 Control(control),
71 CipherKey(NULL),
72 Counter(0),
73 BytesLeft(0)
74{
75}
76
77
78/***********************************************************************************************
79 * PKPipe::Put_To -- Chains one pipe to another. *
80 * *
81 * This handles linking of one pipe to this pipe. Data will flow from this PKPipe to the *
82 * pipe segment specified. Special handling is done so that piping actually flows to the *
83 * embedded blowfish pipe and then flows to the designated pipe. *
84 * *
85 * INPUT: pipe -- Pointer to the pipe that this pipe segment is to send data to. *
86 * *
87 * OUTPUT: none *
88 * *
89 * WARNINGS: none *
90 * *
91 * HISTORY: *
92 * 07/12/1996 JLB : Created. *
93 *=============================================================================================*/
94void PKPipe::Put_To(Pipe * pipe)
95{
96 if (BF.ChainTo != pipe) {
97 if (pipe != NULL && pipe->ChainFrom != NULL) {
98 pipe->ChainFrom->Put_To(NULL);
99 pipe->ChainFrom = NULL;
100 }
101
102 if (BF.ChainTo != NULL) {
103 BF.ChainTo->ChainFrom = NULL;
104 }
105 BF.ChainTo = pipe;
106 if (pipe != NULL) {
107 pipe->ChainFrom = &BF;
108 }
109 BF.ChainFrom = this;
110 ChainTo = &BF;
111 }
112}
113
114
115/***********************************************************************************************
116 * PKPipe::Key -- Submit a key to enable processing of data flow. *
117 * *
118 * This routine must be called with a valid key pointer in order for encryption/description *
119 * to be performed on the data stream. Prior to calling this routine or after calling this *
120 * routine with a NULL pointer, the data stream will pass through this pipe without *
121 * modification. *
122 * *
123 * INPUT: key -- Pointer to the key to use for processing. Pass NULL if process is to be *
124 * terminated. *
125 * *
126 * OUTPUT: none *
127 * *
128 * WARNINGS: none *
129 * *
130 * HISTORY: *
131 * 07/07/1996 JLB : Created. *
132 *=============================================================================================*/
133void PKPipe::Key(PKey const * key)
134{
135 if (key == NULL) {
136 Flush();
137 IsGettingKey = false;
138 }
139 CipherKey = key;
140
141 if (CipherKey != NULL) {
142 IsGettingKey = true;
143 if (Control == DECRYPT) {
144 Counter = BytesLeft = Encrypted_Key_Length();
145 }
146 }
147}
148
149
150/***********************************************************************************************
151 * PKPipe::Put -- Submit data to the pipe for processing. *
152 * *
153 * This routine (if processing as been enabled by a previous key submission) will *
154 * encrypt or decrypt the data stream that passes through it. When encrypting, the data *
155 * stream will increase in size by about 10% (bit it varies according to the key used). *
156 * *
157 * INPUT: source -- Pointer to the data to be submitted to the pipe stream. *
158 * *
159 * length -- The number of bytes submitted. *
160 * *
161 * OUTPUT: Returns with the actual number of byte output at the final end of the pipe. *
162 * *
163 * WARNINGS: none *
164 * *
165 * HISTORY: *
166 * 07/07/1996 JLB : Created. *
167 *=============================================================================================*/
168int PKPipe::Put(void const * source, int length)
169{
170 /*
171 ** If the parameter seem illegal, then pass the pipe request to the
172 ** next pipe in the chain and let them deal with it.
173 */
174 if (source == NULL || length < 1 || CipherKey == NULL) {
175 return(Pipe::Put(source, length));
176 }
177
178 int total = 0;
179
180 /*
181 ** Perform a special process if the this is the first part of the data flow. The special
182 ** key must be processed first. After this initial key processing, the rest of the data flow
183 ** is processed by the blowfish pipe and ignored by the PKPipe.
184 */
185 if (IsGettingKey) {
186
187 /*
188 ** When encrypting, first make the key block and then pass the data through the
189 ** normal blowfish processor.
190 */
191 if (Control == ENCRYPT) {
192
193 /*
194 ** Generate the largest blowfish key possible.
195 */
196 char buffer[MAX_KEY_BLOCK_SIZE];
197 memset(buffer, '\0', sizeof(buffer));
198 Rand.Get(buffer, BLOWFISH_KEY_SIZE);
199
200 /*
201 ** Encrypt the blowfish key (along with any necessary pad bytes).
202 */
203 int didput = CipherKey->Encrypt(buffer, Plain_Key_Length(), Buffer);
204 total += Pipe::Put(Buffer, didput);
205 BF.Key(buffer, BLOWFISH_KEY_SIZE);
206
207 IsGettingKey = false;
208
209 } else {
210
211 /*
212 ** First try to accumulate a full key.
213 */
214 int toget = (BytesLeft < length) ? BytesLeft : length;
215 memmove(&Buffer[Counter-BytesLeft], source, toget);
216 length -= toget;
217 BytesLeft -= toget;
218 source = (char *)source + toget;
219
220 /*
221 ** If a full key has been accumulated, then decrypt it and feed the
222 ** key to the blowfish engine.
223 */
224 if (BytesLeft == 0) {
225 char buffer[MAX_KEY_BLOCK_SIZE];
226 CipherKey->Decrypt(Buffer, Counter, buffer);
227 BF.Key(buffer, BLOWFISH_KEY_SIZE);
228
229 IsGettingKey = false;
230 }
231 }
232 }
233
234 /*
235 ** If there are any remaining bytes to pipe through, then
236 ** pipe them through now -- they will be processed by the
237 ** blowfish engine.
238 */
239 total += Pipe::Put(source, length);
240 return(total);
241}
242
243
244/***********************************************************************************************
245 * PKPipe::Encrypted_Key_Length -- Fetch the encrypted key length. *
246 * *
247 * This returns the total number of bytes (after encryption) that the blowfish key will *
248 * consume. It should be possible to get a block of this size, then pass it to the *
249 * public key decrypter and the result will be the full blowfish key. *
250 * *
251 * INPUT: none *
252 * *
253 * OUTPUT: Returns with the number of bytes that the encrypted blowfish key required. *
254 * *
255 * WARNINGS: none *
256 * *
257 * HISTORY: *
258 * 07/11/1996 JLB : Created. *
259 *=============================================================================================*/
260int PKPipe::Encrypted_Key_Length(void) const
261{
262 if (CipherKey == NULL) return(0);
263 return(CipherKey->Block_Count(BLOWFISH_KEY_SIZE) * CipherKey->Crypt_Block_Size());
264}
265
266
267/***********************************************************************************************
268 * PKPipe::Plain_Key_Length -- Returns the number of bytes to encrypt key. *
269 * *
270 * This is the number of plain (unencrypted) bytes that the blowfish key will take up. This *
271 * is actually the number of plain blocks minimum that can contain the full blowfish *
272 * key. The public key cryptography system encrypts in whole blocks only. *
273 * *
274 * INPUT: none *
275 * *
276 * OUTPUT: Returns with the total number of bytes that will contain the full blowfish key *
277 * and still be an even block size for the public key cryptography process. *
278 * *
279 * WARNINGS: This value is probably be larger than the actual blowfish key length. *
280 * *
281 * HISTORY: *
282 * 07/11/1996 JLB : Created. *
283 *=============================================================================================*/
284int PKPipe::Plain_Key_Length(void) const
285{
286 if (CipherKey == NULL) return(0);
287 return(CipherKey->Block_Count(BLOWFISH_KEY_SIZE) * CipherKey->Plain_Block_Size());
288}
#define NULL
Definition BaseType.h:92
@ true
Definition bool.h:59
virtual void Put_To(Pipe *pipe)
Definition pkpipe.cpp:94
PKPipe(CryptControl control, RandomStraw &rnd)
Definition pkpipe.cpp:66
CryptControl
Definition pkpipe.h:54
@ ENCRYPT
Definition pkpipe.h:55
@ DECRYPT
Definition pkpipe.h:56
void Key(PKey const *key)
Definition pkpipe.cpp:133
virtual int Put(void const *source, int length)
Definition pkpipe.cpp:168
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 void Put_To(Pipe *pipe)
Definition pipe.cpp:92
Pipe * ChainTo
Definition PIPE.H:65
virtual int Flush(void)
Definition pipe.cpp:158
virtual int Put(void const *source, int slen)
Definition pipe.cpp:131
Pipe * ChainFrom
Definition PIPE.H:66