UFO: Alien Invasion
Toggle main menu visibility
Loading...
Searching...
No Matches
sha1.cpp
Go to the documentation of this file.
1
/*
2
* sha1.c
3
*
4
* Copyright (C) 1998, 2009
5
* Paul E. Jones <paulej@packetizer.com>
6
* All Rights Reserved
7
*
8
*****************************************************************************
9
* $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $
10
*****************************************************************************
11
*
12
* Description:
13
* This file implements the Secure Hashing Standard as defined
14
* in FIPS PUB 180-1 published April 17, 1995.
15
*
16
* The Secure Hashing Standard, which uses the Secure Hashing
17
* Algorithm (SHA), produces a 160-bit message digest for a
18
* given data stream. In theory, it is highly improbable that
19
* two messages will produce the same message digest. Therefore,
20
* this algorithm can serve as a means of providing a "fingerprint"
21
* for a message.
22
*
23
* Portability Issues:
24
* SHA-1 is defined in terms of 32-bit "words". This code was
25
* written with the expectation that the processor has at least
26
* a 32-bit machine word size. If the machine word size is larger,
27
* the code should still function properly. One caveat to that
28
* is that the input functions taking characters and character
29
* arrays assume that only 8 bits of information are stored in each
30
* character.
31
*
32
* Caveats:
33
* SHA-1 is designed to work with messages less than 2^64 bits
34
* long. Although SHA-1 allows a message digest to be generated for
35
* messages of any number of bits less than 2^64, this
36
* implementation only works with messages with a length that is a
37
* multiple of the size of an 8-bit character.
38
*
39
*/
40
41
#include "
sha1.h
"
42
#include "
filesys.h
"
43
#include "
../shared/shared.h
"
44
45
/*
46
* Define the circular shift macro
47
*/
48
#define SHA1CircularShift(bits,word) \
49
((((word) << (bits)) & 0xFFFFFFFF) | \
50
((word) >> (32-(bits))))
51
52
/* Function prototypes */
53
static
void
Com_SHA1ProcessMessageBlock
(
SHA1Context
*);
54
static
void
Com_SHA1PadMessage
(
SHA1Context
*);
55
72
void
Com_SHA1Reset
(
SHA1Context
*context)
73
{
74
context->
Length_Low
= 0;
75
context->
Length_High
= 0;
76
context->
Message_Block_Index
= 0;
77
78
context->
Message_Digest
[0] = 0x67452301;
79
context->
Message_Digest
[1] = 0xEFCDAB89;
80
context->
Message_Digest
[2] = 0x98BADCFE;
81
context->
Message_Digest
[3] = 0x10325476;
82
context->
Message_Digest
[4] = 0xC3D2E1F0;
83
84
context->
Computed
= 0;
85
context->
Corrupted
= 0;
86
}
87
104
bool
Com_SHA1Result
(
SHA1Context
*context)
105
{
106
if
(context->
Corrupted
) {
107
return
false
;
108
}
109
110
if
(!context->
Computed
) {
111
Com_SHA1PadMessage
(context);
112
context->
Computed
= 1;
113
}
114
115
return
true
;
116
}
117
139
void
Com_SHA1Input
(
SHA1Context
*context,
const
unsigned
char
* message_array,
unsigned
length
)
140
{
141
if
(!
length
) {
142
return
;
143
}
144
145
if
(context->
Computed
|| context->
Corrupted
) {
146
context->
Corrupted
= 1;
147
return
;
148
}
149
150
while
(
length
-- && !context->
Corrupted
) {
151
context->
Message_Block
[context->
Message_Block_Index
++] = (*message_array & 0xFF);
152
153
context->
Length_Low
+= 8;
154
/* Force it to 32 bits */
155
context->
Length_Low
&= 0xFFFFFFFF;
156
if
(context->
Length_Low
== 0) {
157
context->
Length_High
++;
158
/* Force it to 32 bits */
159
context->
Length_High
&= 0xFFFFFFFF;
160
if
(context->
Length_High
== 0) {
161
/* Message is too long */
162
context->
Corrupted
= 1;
163
}
164
}
165
166
if
(context->
Message_Block_Index
== 64) {
167
Com_SHA1ProcessMessageBlock
(context);
168
}
169
170
message_array++;
171
}
172
}
173
192
static
void
Com_SHA1ProcessMessageBlock
(
SHA1Context
*context)
193
{
194
const
unsigned
K[] =
/* Constants defined in SHA-1 */
195
{ 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 };
196
unsigned
W[80];
/* Word sequence*/
197
198
/*
199
* Initialize the first 16 words in the array W
200
*/
201
for
(
int
t = 0; t < 16; t++) {
202
W[t] = ((unsigned) context->
Message_Block
[t * 4]) << 24;
203
W[t] |= ((unsigned) context->
Message_Block
[t * 4 + 1]) << 16;
204
W[t] |= ((unsigned) context->
Message_Block
[t * 4 + 2]) << 8;
205
W[t] |= ((unsigned) context->
Message_Block
[t * 4 + 3]);
206
}
207
208
for
(
int
t = 16; t < 80; t++) {
209
W[t] =
SHA1CircularShift
(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
210
}
211
212
unsigned
A = context->
Message_Digest
[0];
213
unsigned
B = context->
Message_Digest
[1];
214
unsigned
C = context->
Message_Digest
[2];
215
unsigned
D = context->
Message_Digest
[3];
216
unsigned
E
= context->
Message_Digest
[4];
217
218
for
(
int
t = 0; t < 20; t++) {
219
unsigned
temp =
SHA1CircularShift
(5,A) + ((B & C) | ((~B) & D)) +
E
+ W[t] + K[0];
220
temp &= 0xFFFFFFFF;
221
E
= D;
222
D = C;
223
C =
SHA1CircularShift
(30,B);
224
B = A;
225
A = temp;
226
}
227
228
for
(
int
t = 20; t < 40; t++) {
229
unsigned
temp =
SHA1CircularShift
(5,A) + (B ^ C ^ D) +
E
+ W[t] + K[1];
230
temp &= 0xFFFFFFFF;
231
E
= D;
232
D = C;
233
C =
SHA1CircularShift
(30,B);
234
B = A;
235
A = temp;
236
}
237
238
for
(
int
t = 40; t < 60; t++) {
239
unsigned
temp =
SHA1CircularShift
(5,A) + ((B & C) | (B & D) | (C & D)) +
E
+ W[t] + K[2];
240
temp &= 0xFFFFFFFF;
241
E
= D;
242
D = C;
243
C =
SHA1CircularShift
(30,B);
244
B = A;
245
A = temp;
246
}
247
248
for
(
int
t = 60; t < 80; t++) {
249
unsigned
temp =
SHA1CircularShift
(5,A) + (B ^ C ^ D) +
E
+ W[t] + K[3];
250
temp &= 0xFFFFFFFF;
251
E
= D;
252
D = C;
253
C =
SHA1CircularShift
(30,B);
254
B = A;
255
A = temp;
256
}
257
258
context->
Message_Digest
[0] = (context->
Message_Digest
[0] + A) & 0xFFFFFFFF;
259
context->
Message_Digest
[1] = (context->
Message_Digest
[1] + B) & 0xFFFFFFFF;
260
context->
Message_Digest
[2] = (context->
Message_Digest
[2] + C) & 0xFFFFFFFF;
261
context->
Message_Digest
[3] = (context->
Message_Digest
[3] + D) & 0xFFFFFFFF;
262
context->
Message_Digest
[4] = (context->
Message_Digest
[4] +
E
) & 0xFFFFFFFF;
263
264
context->
Message_Block_Index
= 0;
265
}
266
289
static
void
Com_SHA1PadMessage
(
SHA1Context
*context)
290
{
291
/*
292
* Check to see if the current message block is too small to hold
293
* the initial padding bits and length. If so, we will pad the
294
* block, process it, and then continue padding into a second
295
* block.
296
*/
297
if
(context->
Message_Block_Index
> 55) {
298
context->
Message_Block
[context->
Message_Block_Index
++] = 0x80;
299
while
(context->
Message_Block_Index
< 64) {
300
context->
Message_Block
[context->
Message_Block_Index
++] = 0;
301
}
302
303
Com_SHA1ProcessMessageBlock
(context);
304
305
while
(context->
Message_Block_Index
< 56) {
306
context->
Message_Block
[context->
Message_Block_Index
++] = 0;
307
}
308
}
else
{
309
context->
Message_Block
[context->
Message_Block_Index
++] = 0x80;
310
while
(context->
Message_Block_Index
< 56) {
311
context->
Message_Block
[context->
Message_Block_Index
++] = 0;
312
}
313
}
314
315
/*
316
* Store the message length as the last 8 octets
317
*/
318
context->
Message_Block
[56] = (context->
Length_High
>> 24) & 0xFF;
319
context->
Message_Block
[57] = (context->
Length_High
>> 16) & 0xFF;
320
context->
Message_Block
[58] = (context->
Length_High
>> 8) & 0xFF;
321
context->
Message_Block
[59] = (context->
Length_High
) & 0xFF;
322
context->
Message_Block
[60] = (context->
Length_Low
>> 24) & 0xFF;
323
context->
Message_Block
[61] = (context->
Length_Low
>> 16) & 0xFF;
324
context->
Message_Block
[62] = (context->
Length_Low
>> 8) & 0xFF;
325
context->
Message_Block
[63] = (context->
Length_Low
) & 0xFF;
326
327
Com_SHA1ProcessMessageBlock
(context);
328
}
329
330
bool
Com_SHA1File
(
const
char
*
filename
,
char
digest[41])
331
{
332
qFILE
f
;
333
const
int
filelen =
FS_OpenFile
(
filename
, &
f
,
FILE_READ
);
334
if
(filelen < 1)
335
return
false
;
336
337
SHA1Context
sha;
338
Com_SHA1Reset
(&sha);
339
340
byte
buf
[1024];
341
for
(;;) {
342
const
int
n =
FS_Read
(
buf
,
sizeof
(
buf
), &
f
);
343
if
(n < 1)
344
break
;
345
Com_SHA1Input
(&sha,
buf
, n);
346
}
347
348
if
(!
Com_SHA1Result
(&sha)) {
349
return
false
;
350
}
351
digest[0] =
'\0'
;
352
for
(
int
i
= 0;
i
< 5;
i
++) {
353
Q_strcat
(digest, 41,
"%02x"
, sha.
Message_Digest
[
i
]);
354
}
355
return
true
;
356
}
357
358
bool
Com_SHA1Buffer
(
const
unsigned
char
*
buf
,
unsigned
int
len
,
char
digest[41])
359
{
360
if
(
len
< 1)
361
return
false
;
362
363
SHA1Context
sha;
364
Com_SHA1Reset
(&sha);
365
Com_SHA1Input
(&sha,
buf
,
len
);
366
367
if
(!
Com_SHA1Result
(&sha)) {
368
return
false
;
369
}
370
digest[0] =
'\0'
;
371
for
(
int
i
= 0;
i
< 5;
i
++) {
372
Q_strcat
(digest, 41,
"%02x"
, sha.
Message_Digest
[
i
]);
373
}
374
return
true
;
375
}
E
#define E(x)
FS_Read
int FS_Read(void *buffer, int len, qFILE *f)
Definition
files.cpp:371
FS_OpenFile
int FS_OpenFile(const char *filename, qFILE *file, filemode_t mode)
Finds and opens the file in the search path.
Definition
files.cpp:162
filesys.h
Filesystem header file.
FILE_READ
@ FILE_READ
Definition
filesys.h:111
filename
const char * filename
Definition
ioapi.h:41
buf
voidpf void * buf
Definition
ioapi.h:42
len
QGL_EXTERN GLuint GLchar GLuint * len
Definition
r_gl.h:99
length
QGL_EXTERN GLuint GLsizei GLsizei * length
Definition
r_gl.h:110
f
QGL_EXTERN GLfloat f
Definition
r_gl.h:114
i
QGL_EXTERN GLint i
Definition
r_gl.h:113
Com_SHA1File
bool Com_SHA1File(const char *filename, char digest[41])
Definition
sha1.cpp:330
Com_SHA1Input
void Com_SHA1Input(SHA1Context *context, const unsigned char *message_array, unsigned length)
Definition
sha1.cpp:139
Com_SHA1Buffer
bool Com_SHA1Buffer(const unsigned char *buf, unsigned int len, char digest[41])
Definition
sha1.cpp:358
Com_SHA1ProcessMessageBlock
static void Com_SHA1ProcessMessageBlock(SHA1Context *)
Definition
sha1.cpp:192
Com_SHA1Result
bool Com_SHA1Result(SHA1Context *context)
Definition
sha1.cpp:104
Com_SHA1PadMessage
static void Com_SHA1PadMessage(SHA1Context *)
Definition
sha1.cpp:289
Com_SHA1Reset
void Com_SHA1Reset(SHA1Context *context)
Definition
sha1.cpp:72
SHA1CircularShift
#define SHA1CircularShift(bits, word)
Definition
sha1.cpp:48
sha1.h
shared.h
Q_strcat
void Q_strcat(char *dest, size_t destsize, const char *format,...)
Safely (without overflowing the destination buffer) concatenates two strings.
Definition
shared.cpp:475
SHA1Context
Definition
sha1.h:43
SHA1Context::Message_Digest
unsigned Message_Digest[5]
Definition
sha1.h:44
SHA1Context::Computed
int Computed
Definition
sha1.h:52
SHA1Context::Message_Block_Index
int Message_Block_Index
Definition
sha1.h:50
SHA1Context::Length_Low
unsigned Length_Low
Definition
sha1.h:46
SHA1Context::Message_Block
unsigned char Message_Block[64]
Definition
sha1.h:49
SHA1Context::Corrupted
int Corrupted
Definition
sha1.h:53
SHA1Context::Length_High
unsigned Length_High
Definition
sha1.h:47
qFILE
Definition
filesys.h:54
src
common
sha1.cpp
Generated on __DATE__ __TIME__ for UFO: Alien Invasion by
1.17.0