CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/ext/libkirk/SHA1.c
Views: 1401
1
/* sha1.c : Implementation of the Secure Hash Algorithm */
2
3
/* SHA: NIST's Secure Hash Algorithm */
4
5
/* This version written November 2000 by David Ireland of
6
DI Management Services Pty Limited <[email protected]>
7
8
Adapted from code in the Python Cryptography Toolkit,
9
version 1.0.0 by A.M. Kuchling 1995.
10
*/
11
12
/* AM Kuchling's posting:-
13
Based on SHA code originally posted to sci.crypt by Peter Gutmann
14
in message <[email protected]>.
15
Modified to test for endianness on creation of SHA objects by AMK.
16
Also, the original specification of SHA was found to have a weakness
17
by NSA/NIST. This code implements the fixed version of SHA.
18
*/
19
20
/* Here's the first paragraph of Peter Gutmann's posting:
21
22
The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
23
SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
24
what's changed in the new version. The fix is a simple change which involves
25
adding a single rotate in the initial expansion function. It is unknown
26
whether this is an optimal solution to the problem which was discovered in the
27
SHA or whether it's simply a bandaid which fixes the problem with a minimum of
28
effort (for example the reengineering of a great many Capstone chips).
29
*/
30
31
/* h files included here to make this just one file ... */
32
33
/* global.h */
34
35
36
37
/* sha.c */
38
#include "SHA1.h"
39
40
#include <stdio.h>
41
#include <string.h>
42
43
static void SHAtoByte(BYTE *output, UINT4 *input, unsigned int len);
44
45
/* The SHS block size and message digest sizes, in bytes */
46
47
#define SHS_DATASIZE 64
48
#define SHS_DIGESTSIZE 20
49
50
51
/* The SHS f()-functions. The f1 and f3 functions can be optimized to
52
save one boolean operation each - thanks to Rich Schroeppel,
53
[email protected] for discovering this */
54
55
/*#define f1(x,y,z) ( ( x & y ) | ( ~x & z ) ) // Rounds 0-19 */
56
#define f1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) /* Rounds 0-19 */
57
#define f2(x,y,z) ( x ^ y ^ z ) /* Rounds 20-39 */
58
/*#define f3(x,y,z) ( ( x & y ) | ( x & z ) | ( y & z ) ) // Rounds 40-59 */
59
#define f3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) /* Rounds 40-59 */
60
#define f4(x,y,z) ( x ^ y ^ z ) /* Rounds 60-79 */
61
62
/* The SHS Mysterious Constants */
63
64
#define K1 0x5A827999L /* Rounds 0-19 */
65
#define K2 0x6ED9EBA1L /* Rounds 20-39 */
66
#define K3 0x8F1BBCDCL /* Rounds 40-59 */
67
#define K4 0xCA62C1D6L /* Rounds 60-79 */
68
69
/* SHS initial values */
70
71
#define h0init 0x67452301L
72
#define h1init 0xEFCDAB89L
73
#define h2init 0x98BADCFEL
74
#define h3init 0x10325476L
75
#define h4init 0xC3D2E1F0L
76
77
/* Note that it may be necessary to add parentheses to these macros if they
78
are to be called with expressions as arguments */
79
/* 32-bit rotate left - kludged with shifts */
80
81
#define ROTL(n,X) ( ( ( X ) << n ) | ( ( X ) >> ( 32 - n ) ) )
82
83
/* The initial expanding function. The hash function is defined over an
84
80-UINT2 expanded input array W, where the first 16 are copies of the input
85
data, and the remaining 64 are defined by
86
87
W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
88
89
This implementation generates these values on the fly in a circular
90
buffer - thanks to Colin Plumb, [email protected] for this
91
optimization.
92
93
The updated SHS changes the expanding function by adding a rotate of 1
94
bit. Thanks to Jim Gillogly, [email protected], and an anonymous contributor
95
for this information */
96
97
#define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
98
W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] ) ) )
99
100
101
/* The prototype SHS sub-round. The fundamental sub-round is:
102
103
a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
104
b' = a;
105
c' = ROTL( 30, b );
106
d' = c;
107
e' = d;
108
109
but this is implemented by unrolling the loop 5 times and renaming the
110
variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
111
This code is then replicated 20 times for each of the 4 functions, using
112
the next 20 values from the W[] array each time */
113
114
#define subRound(a, b, c, d, e, f, k, data) \
115
( e += ROTL( 5, a ) + f( b, c, d ) + k + data, b = ROTL( 30, b ) )
116
117
/* Initialize the SHS values */
118
119
void SHAInit(SHA_CTX *shsInfo)
120
{
121
endianTest(&shsInfo->Endianness);
122
/* Set the h-vars to their initial values */
123
shsInfo->digest[ 0 ] = h0init;
124
shsInfo->digest[ 1 ] = h1init;
125
shsInfo->digest[ 2 ] = h2init;
126
shsInfo->digest[ 3 ] = h3init;
127
shsInfo->digest[ 4 ] = h4init;
128
129
/* Initialise bit count */
130
shsInfo->countLo = shsInfo->countHi = 0;
131
}
132
133
134
/* Perform the SHS transformation. Note that this code, like MD5, seems to
135
break some optimizing compilers due to the complexity of the expressions
136
and the size of the basic block. It may be necessary to split it into
137
sections, e.g. based on the four subrounds
138
139
Note that this corrupts the shsInfo->data area */
140
141
static void SHSTransform( UINT4 *digest, UINT4 *data )
142
{
143
UINT4 A, B, C, D, E; /* Local vars */
144
UINT4 eData[ 16 ]; /* Expanded data */
145
146
/* Set up first buffer and local data buffer */
147
A = digest[ 0 ];
148
B = digest[ 1 ];
149
C = digest[ 2 ];
150
D = digest[ 3 ];
151
E = digest[ 4 ];
152
memcpy( (POINTER)eData, (POINTER)data, SHS_DATASIZE );
153
154
/* Heavy mangling, in 4 sub-rounds of 20 interations each. */
155
subRound( A, B, C, D, E, f1, K1, eData[ 0 ] );
156
subRound( E, A, B, C, D, f1, K1, eData[ 1 ] );
157
subRound( D, E, A, B, C, f1, K1, eData[ 2 ] );
158
subRound( C, D, E, A, B, f1, K1, eData[ 3 ] );
159
subRound( B, C, D, E, A, f1, K1, eData[ 4 ] );
160
subRound( A, B, C, D, E, f1, K1, eData[ 5 ] );
161
subRound( E, A, B, C, D, f1, K1, eData[ 6 ] );
162
subRound( D, E, A, B, C, f1, K1, eData[ 7 ] );
163
subRound( C, D, E, A, B, f1, K1, eData[ 8 ] );
164
subRound( B, C, D, E, A, f1, K1, eData[ 9 ] );
165
subRound( A, B, C, D, E, f1, K1, eData[ 10 ] );
166
subRound( E, A, B, C, D, f1, K1, eData[ 11 ] );
167
subRound( D, E, A, B, C, f1, K1, eData[ 12 ] );
168
subRound( C, D, E, A, B, f1, K1, eData[ 13 ] );
169
subRound( B, C, D, E, A, f1, K1, eData[ 14 ] );
170
subRound( A, B, C, D, E, f1, K1, eData[ 15 ] );
171
subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) );
172
subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) );
173
subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) );
174
subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) );
175
176
subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) );
177
subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) );
178
subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) );
179
subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) );
180
subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) );
181
subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) );
182
subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) );
183
subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) );
184
subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) );
185
subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) );
186
subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) );
187
subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) );
188
subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) );
189
subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) );
190
subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) );
191
subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) );
192
subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) );
193
subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) );
194
subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) );
195
subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) );
196
197
subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) );
198
subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) );
199
subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) );
200
subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) );
201
subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) );
202
subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) );
203
subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) );
204
subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) );
205
subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) );
206
subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) );
207
subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) );
208
subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) );
209
subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) );
210
subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) );
211
subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) );
212
subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) );
213
subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) );
214
subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) );
215
subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) );
216
subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) );
217
218
subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) );
219
subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) );
220
subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) );
221
subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) );
222
subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) );
223
subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) );
224
subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) );
225
subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) );
226
subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) );
227
subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) );
228
subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) );
229
subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) );
230
subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) );
231
subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) );
232
subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) );
233
subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) );
234
subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) );
235
subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) );
236
subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) );
237
subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) );
238
239
/* Build message digest */
240
digest[ 0 ] += A;
241
digest[ 1 ] += B;
242
digest[ 2 ] += C;
243
digest[ 3 ] += D;
244
digest[ 4 ] += E;
245
}
246
247
/* When run on a little-endian CPU we need to perform byte reversal on an
248
array of long words. */
249
250
static void longReverse(UINT4 *buffer, int byteCount, int Endianness )
251
{
252
UINT4 value;
253
254
if (Endianness==TRUE) return;
255
byteCount /= sizeof( UINT4 );
256
while( byteCount-- )
257
{
258
value = *buffer;
259
value = ( ( value & 0xFF00FF00L ) >> 8 ) | \
260
( ( value & 0x00FF00FFL ) << 8 );
261
*buffer++ = ( value << 16 ) | ( value >> 16 );
262
}
263
}
264
265
/* Update SHS for a block of data */
266
267
void SHAUpdate(SHA_CTX *shsInfo, BYTE *buffer, int count)
268
{
269
UINT4 tmp;
270
int dataCount;
271
272
/* Update bitcount */
273
tmp = shsInfo->countLo;
274
if ( ( shsInfo->countLo = tmp + ( ( UINT4 ) count << 3 ) ) < tmp )
275
shsInfo->countHi++; /* Carry from low to high */
276
shsInfo->countHi += count >> 29;
277
278
/* Get count of bytes already in data */
279
dataCount = ( int ) ( tmp >> 3 ) & 0x3F;
280
281
/* Handle any leading odd-sized chunks */
282
if( dataCount )
283
{
284
BYTE *p = ( BYTE * ) shsInfo->data + dataCount;
285
286
dataCount = SHS_DATASIZE - dataCount;
287
if( count < dataCount )
288
{
289
memcpy( p, buffer, count );
290
return;
291
}
292
memcpy( p, buffer, dataCount );
293
longReverse( shsInfo->data, SHS_DATASIZE, shsInfo->Endianness);
294
SHSTransform( shsInfo->digest, shsInfo->data );
295
buffer += dataCount;
296
count -= dataCount;
297
}
298
299
/* Process data in SHS_DATASIZE chunks */
300
while( count >= SHS_DATASIZE )
301
{
302
memcpy( (POINTER)shsInfo->data, (POINTER)buffer, SHS_DATASIZE );
303
longReverse( shsInfo->data, SHS_DATASIZE, shsInfo->Endianness );
304
SHSTransform( shsInfo->digest, shsInfo->data );
305
buffer += SHS_DATASIZE;
306
count -= SHS_DATASIZE;
307
}
308
309
/* Handle any remaining bytes of data. */
310
memcpy( (POINTER)shsInfo->data, (POINTER)buffer, count );
311
}
312
313
/* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern
314
1 0* (64-bit count of bits processed, MSB-first) */
315
316
void SHAFinal(BYTE *output, SHA_CTX *shsInfo)
317
{
318
int count;
319
BYTE *dataPtr;
320
321
/* Compute number of bytes mod 64 */
322
count = ( int ) shsInfo->countLo;
323
count = ( count >> 3 ) & 0x3F;
324
325
/* Set the first char of padding to 0x80. This is safe since there is
326
always at least one byte free */
327
dataPtr = ( BYTE * ) shsInfo->data + count;
328
*dataPtr++ = 0x80;
329
330
/* Bytes of padding needed to make 64 bytes */
331
count = SHS_DATASIZE - 1 - count;
332
333
/* Pad out to 56 mod 64 */
334
if( count < 8 )
335
{
336
/* Two lots of padding: Pad the first block to 64 bytes */
337
memset( dataPtr, 0, count );
338
longReverse( shsInfo->data, SHS_DATASIZE, shsInfo->Endianness );
339
SHSTransform( shsInfo->digest, shsInfo->data );
340
341
/* Now fill the next block with 56 bytes */
342
memset( (POINTER)shsInfo->data, 0, SHS_DATASIZE - 8 );
343
}
344
else
345
/* Pad block to 56 bytes */
346
memset( dataPtr, 0, count - 8 );
347
348
/* Append length in bits and transform */
349
shsInfo->data[ 14 ] = shsInfo->countHi;
350
shsInfo->data[ 15 ] = shsInfo->countLo;
351
352
longReverse( shsInfo->data, SHS_DATASIZE - 8, shsInfo->Endianness );
353
SHSTransform( shsInfo->digest, shsInfo->data );
354
355
/* Output to an array of bytes */
356
SHAtoByte(output, shsInfo->digest, SHS_DIGESTSIZE);
357
358
/* Zeroise sensitive stuff */
359
memset((POINTER)shsInfo, 0, sizeof(*shsInfo));
360
}
361
362
static void SHAtoByte(BYTE *output, UINT4 *input, unsigned int len)
363
{ /* Output SHA digest in byte array */
364
unsigned int i, j;
365
366
for(i = 0, j = 0; j < len; i++, j += 4)
367
{
368
output[j+3] = (BYTE)( input[i] & 0xff);
369
output[j+2] = (BYTE)((input[i] >> 8 ) & 0xff);
370
output[j+1] = (BYTE)((input[i] >> 16) & 0xff);
371
output[j ] = (BYTE)((input[i] >> 24) & 0xff);
372
}
373
}
374
375
376
377
378
/* endian.c */
379
380
void endianTest(int *endian_ness)
381
{
382
if((*(unsigned short *) ("#S") >> 8) == '#')
383
{
384
/* printf("Big endian = no change\n"); */
385
*endian_ness = !(0);
386
}
387
else
388
{
389
/* printf("Little endian = swap\n"); */
390
*endian_ness = 0;
391
}
392
}
393
394