update vibration handling
[pcsx_rearmed.git] / deps / libretro-common / utils / sha1.c
CommitLineData
3719602c
PC
1/*
2 * sha1.h
3 *
4 * Copyright (C) 1998, 2009
5 * Paul E. Jones <paulej@packetizer.com>
6 * All Rights Reserved
7 *
8 *****************************************************************************
9 * $Id: sha1.h 12 2009-06-22 19:34:25Z paulej $
10 *****************************************************************************
11 *
12 * Description:
13 * This class implements the Secure Hashing Standard as defined
14 * in FIPS PUB 180-1 published April 17, 1995.
15 *
16 * Many of the variable names in the SHA1Context, especially the
17 * single character names, were used because those were the names
18 * used in the publication.
19 *
20 * Please read the file sha1.c for more information.
21 *
22 */
23
24#include <stdio.h>
25#include <string.h>
26#ifdef WIN32
27#include <io.h>
28#endif
29#include <fcntl.h>
30#include <string/stdstring.h>
31
32#ifndef _SHA1_H_
33#define _SHA1_H_
34
35/*
36 * This structure will hold context information for the hashing
37 * operation
38 */
39typedef struct SHA1Context
40{
41 unsigned Message_Digest[5]; /* Message Digest (output) */
42
43 unsigned Length_Low; /* Message length in bits */
44 unsigned Length_High; /* Message length in bits */
45
46 unsigned char Message_Block[64]; /* 512-bit message blocks */
47 int Message_Block_Index; /* Index into message block array */
48
49 int Computed; /* Is the digest computed? */
50 int Corrupted; /* Is the message digest corruped? */
51} SHA1Context;
52
53/*
54 * Function Prototypes
55 */
56void SHA1Reset(SHA1Context *);
57int SHA1Result(SHA1Context *);
58void SHA1Input( SHA1Context *,
59 const unsigned char *,
60 unsigned);
61
62#endif
63
64/*
65 * sha1.c
66 *
67 * Copyright (C) 1998, 2009
68 * Paul E. Jones <paulej@packetizer.com>
69 * All Rights Reserved
70 *
71 *****************************************************************************
72 * $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $
73 *****************************************************************************
74 *
75 * Description:
76 * This file implements the Secure Hashing Standard as defined
77 * in FIPS PUB 180-1 published April 17, 1995.
78 *
79 * The Secure Hashing Standard, which uses the Secure Hashing
80 * Algorithm (SHA), produces a 160-bit message digest for a
81 * given data stream. In theory, it is highly improbable that
82 * two messages will produce the same message digest. Therefore,
83 * this algorithm can serve as a means of providing a "fingerprint"
84 * for a message.
85 *
86 * Portability Issues:
87 * SHA-1 is defined in terms of 32-bit "words". This code was
88 * written with the expectation that the processor has at least
89 * a 32-bit machine word size. If the machine word size is larger,
90 * the code should still function properly. One caveat to that
91 * is that the input functions taking characters and character
92 * arrays assume that only 8 bits of information are stored in each
93 * character.
94 *
95 * Caveats:
96 * SHA-1 is designed to work with messages less than 2^64 bits
97 * long. Although SHA-1 allows a message digest to be generated for
98 * messages of any number of bits less than 2^64, this
99 * implementation only works with messages with a length that is a
100 * multiple of the size of an 8-bit character.
101 *
102 */
103
104/*#include "sha1.h"*/
105
106/*
107 * Define the circular shift macro
108 */
109#define SHA1CircularShift(bits,word) \
110 ((((word) << (bits)) & 0xFFFFFFFF) | \
111 ((word) >> (32-(bits))))
112
113/* Function prototypes */
114void SHA1ProcessMessageBlock(SHA1Context *);
115void SHA1PadMessage(SHA1Context *);
116
117/*
118 * SHA1Reset
119 *
120 * Description:
121 * This function will initialize the SHA1Context in preparation
122 * for computing a new message digest.
123 *
124 * Parameters:
125 * context: [in/out]
126 * The context to reset.
127 *
128 * Returns:
129 * Nothing.
130 *
131 * Comments:
132 *
133 */
134void SHA1Reset(SHA1Context *context)
135{
136 context->Length_Low = 0;
137 context->Length_High = 0;
138 context->Message_Block_Index = 0;
139
140 context->Message_Digest[0] = 0x67452301;
141 context->Message_Digest[1] = 0xEFCDAB89;
142 context->Message_Digest[2] = 0x98BADCFE;
143 context->Message_Digest[3] = 0x10325476;
144 context->Message_Digest[4] = 0xC3D2E1F0;
145
146 context->Computed = 0;
147 context->Corrupted = 0;
148}
149
150/*
151 * SHA1Result
152 *
153 * Description:
154 * This function will return the 160-bit message digest into the
155 * Message_Digest array within the SHA1Context provided
156 *
157 * Parameters:
158 * context: [in/out]
159 * The context to use to calculate the SHA-1 hash.
160 *
161 * Returns:
162 * 1 if successful, 0 if it failed.
163 *
164 * Comments:
165 *
166 */
167int SHA1Result(SHA1Context *context)
168{
169 if (context->Corrupted)
170 return 0;
171
172 if (!context->Computed)
173 {
174 SHA1PadMessage(context);
175 context->Computed = 1;
176 }
177
178 return 1;
179}
180
181/*
182 * SHA1Input
183 *
184 * Description:
185 * This function accepts an array of octets as the next portion of
186 * the message.
187 *
188 * Parameters:
189 * context: [in/out]
190 * The SHA-1 context to update
191 * message_array: [in]
192 * An array of characters representing the next portion of the
193 * message.
194 * length: [in]
195 * The length of the message in message_array
196 *
197 * Returns:
198 * Nothing.
199 *
200 * Comments:
201 *
202 */
203void SHA1Input( SHA1Context *context,
204 const unsigned char *message_array,
205 unsigned length)
206{
207 if (!length)
208 return;
209
210 if (context->Computed || context->Corrupted)
211 {
212 context->Corrupted = 1;
213 return;
214 }
215
216 while(length-- && !context->Corrupted)
217 {
218 context->Message_Block[context->Message_Block_Index++] =
219 (*message_array & 0xFF);
220
221 context->Length_Low += 8;
222 /* Force it to 32 bits */
223 context->Length_Low &= 0xFFFFFFFF;
224 if (context->Length_Low == 0)
225 {
226 context->Length_High++;
227 /* Force it to 32 bits */
228 context->Length_High &= 0xFFFFFFFF;
229 if (context->Length_High == 0)
230 {
231 /* Message is too long */
232 context->Corrupted = 1;
233 }
234 }
235
236 if (context->Message_Block_Index == 64)
237 SHA1ProcessMessageBlock(context);
238
239 message_array++;
240 }
241}
242
243/*
244 * SHA1ProcessMessageBlock
245 *
246 * Description:
247 * This function will process the next 512 bits of the message
248 * stored in the Message_Block array.
249 *
250 * Parameters:
251 * None.
252 *
253 * Returns:
254 * Nothing.
255 *
256 * Comments:
257 * Many of the variable names in the SHAContext, especially the
258 * single character names, were used because those were the names
259 * used in the publication.
260 *
261 *
262 */
263void SHA1ProcessMessageBlock(SHA1Context *context)
264{
265 const unsigned K[] = /* Constants defined in SHA-1 */
266 {
267 0x5A827999,
268 0x6ED9EBA1,
269 0x8F1BBCDC,
270 0xCA62C1D6
271 };
272 int t; /* Loop counter */
273 unsigned temp; /* Temporary word value */
274 unsigned W[80]; /* Word sequence */
275 unsigned A, B, C, D, E; /* Word buffers */
276
277 /*
278 * Initialize the first 16 words in the array W
279 */
280 for (t = 0; t < 16; t++)
281 {
282 W[t] = ((unsigned) context->Message_Block[t * 4]) << 24;
283 W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16;
284 W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8;
285 W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]);
286 }
287
288 for (t = 16; t < 80; t++)
289 W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
290
291 A = context->Message_Digest[0];
292 B = context->Message_Digest[1];
293 C = context->Message_Digest[2];
294 D = context->Message_Digest[3];
295 E = context->Message_Digest[4];
296
297 for (t = 0; t < 20; t++)
298 {
299 temp = SHA1CircularShift(5,A) +
300 ((B & C) | ((~B) & D)) + E + W[t] + K[0];
301 temp &= 0xFFFFFFFF;
302 E = D;
303 D = C;
304 C = SHA1CircularShift(30,B);
305 B = A;
306 A = temp;
307 }
308
309 for (t = 20; t < 40; t++)
310 {
311 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
312 temp &= 0xFFFFFFFF;
313 E = D;
314 D = C;
315 C = SHA1CircularShift(30,B);
316 B = A;
317 A = temp;
318 }
319
320 for (t = 40; t < 60; t++)
321 {
322 temp = SHA1CircularShift(5,A) +
323 ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
324 temp &= 0xFFFFFFFF;
325 E = D;
326 D = C;
327 C = SHA1CircularShift(30,B);
328 B = A;
329 A = temp;
330 }
331
332 for (t = 60; t < 80; t++)
333 {
334 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
335 temp &= 0xFFFFFFFF;
336 E = D;
337 D = C;
338 C = SHA1CircularShift(30,B);
339 B = A;
340 A = temp;
341 }
342
343 context->Message_Digest[0] =
344 (context->Message_Digest[0] + A) & 0xFFFFFFFF;
345 context->Message_Digest[1] =
346 (context->Message_Digest[1] + B) & 0xFFFFFFFF;
347 context->Message_Digest[2] =
348 (context->Message_Digest[2] + C) & 0xFFFFFFFF;
349 context->Message_Digest[3] =
350 (context->Message_Digest[3] + D) & 0xFFFFFFFF;
351 context->Message_Digest[4] =
352 (context->Message_Digest[4] + E) & 0xFFFFFFFF;
353
354 context->Message_Block_Index = 0;
355}
356
357/*
358 * SHA1PadMessage
359 *
360 * Description:
361 * According to the standard, the message must be padded to an even
362 * 512 bits. The first padding bit must be a '1'. The last 64
363 * bits represent the length of the original message. All bits in
364 * between should be 0. This function will pad the message
365 * according to those rules by filling the Message_Block array
366 * accordingly. It will also call SHA1ProcessMessageBlock()
367 * appropriately. When it returns, it can be assumed that the
368 * message digest has been computed.
369 *
370 * Parameters:
371 * context: [in/out]
372 * The context to pad
373 *
374 * Returns:
375 * Nothing.
376 *
377 * Comments:
378 *
379 */
380void SHA1PadMessage(SHA1Context *context)
381{
382 /*
383 * Check to see if the current message block is too small to hold
384 * the initial padding bits and length. If so, we will pad the
385 * block, process it, and then continue padding into a second
386 * block.
387 */
388 if (context->Message_Block_Index > 55)
389 {
390 context->Message_Block[context->Message_Block_Index++] = 0x80;
391 while(context->Message_Block_Index < 64)
392 context->Message_Block[context->Message_Block_Index++] = 0;
393
394 SHA1ProcessMessageBlock(context);
395
396 while(context->Message_Block_Index < 56)
397 context->Message_Block[context->Message_Block_Index++] = 0;
398 }
399 else
400 {
401 context->Message_Block[context->Message_Block_Index++] = 0x80;
402 while(context->Message_Block_Index < 56)
403 context->Message_Block[context->Message_Block_Index++] = 0;
404 }
405
406 /*
407 * Store the message length as the last 8 octets
408 */
409 context->Message_Block[56] = (context->Length_High >> 24) & 0xFF;
410 context->Message_Block[57] = (context->Length_High >> 16) & 0xFF;
411 context->Message_Block[58] = (context->Length_High >> 8) & 0xFF;
412 context->Message_Block[59] = (context->Length_High) & 0xFF;
413 context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF;
414 context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF;
415 context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF;
416 context->Message_Block[63] = (context->Length_Low) & 0xFF;
417
418 SHA1ProcessMessageBlock(context);
419}