update libchdr
[pcsx_rearmed.git] / deps / libretro-common / hash / lrc_hash.c
CommitLineData
3719602c
PC
1/* Copyright (C) 2010-2020 The RetroArch team
2 *
3 * ---------------------------------------------------------------------------------------
4 * The following license statement only applies to this file (lrc_hash.c).
5 * ---------------------------------------------------------------------------------------
6 *
7 * Permission is hereby granted, free of charge,
8 * to any person obtaining a copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation the rights to
10 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 */
22
23#include <string.h>
24#include <stdio.h>
25#ifdef _WIN32
26#include <io.h>
27#else
28#include <unistd.h>
29#endif
30#include <lrc_hash.h>
31#include <retro_miscellaneous.h>
32#include <retro_endianness.h>
33#include <streams/file_stream.h>
34
35#define LSL32(x, n) ((uint32_t)(x) << (n))
36#define LSR32(x, n) ((uint32_t)(x) >> (n))
37#define ROR32(x, n) (LSR32(x, n) | LSL32(x, 32 - (n)))
38
39/* First 32 bits of the fractional parts of the square roots of the first 8 primes 2..19 */
40static const uint32_t T_H[8] = {
41 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
42};
43
44/* First 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311 */
45static const uint32_t T_K[64] = {
46 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
47 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
48 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
49 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
50 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
51 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
52 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
53 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
54};
55
56/* SHA256 implementation from bSNES. Written by valditx. */
57
58struct sha256_ctx
59{
60 union
61 {
62 uint8_t u8[64];
63 uint32_t u32[16];
64 } in;
65 unsigned inlen;
66
67 uint32_t w[64];
68 uint32_t h[8];
69 uint64_t len;
70};
71
72static void sha256_init(struct sha256_ctx *p)
73{
74 memset(p, 0, sizeof(struct sha256_ctx));
75 memcpy(p->h, T_H, sizeof(T_H));
76}
77
78static void sha256_block(struct sha256_ctx *p)
79{
80 unsigned i;
81 uint32_t s0, s1;
82 uint32_t a, b, c, d, e, f, g, h;
83
84 for (i = 0; i < 16; i++)
85 p->w[i] = load32be(p->in.u32 + i);
86
87 for (i = 16; i < 64; i++)
88 {
89 s0 = ROR32(p->w[i - 15], 7) ^ ROR32(p->w[i - 15], 18) ^ LSR32(p->w[i - 15], 3);
90 s1 = ROR32(p->w[i - 2], 17) ^ ROR32(p->w[i - 2], 19) ^ LSR32(p->w[i - 2], 10);
91 p->w[i] = p->w[i - 16] + s0 + p->w[i - 7] + s1;
92 }
93
94 a = p->h[0]; b = p->h[1]; c = p->h[2]; d = p->h[3];
95 e = p->h[4]; f = p->h[5]; g = p->h[6]; h = p->h[7];
96
97 for (i = 0; i < 64; i++)
98 {
99 uint32_t t1, t2, maj, ch;
100
101 s0 = ROR32(a, 2) ^ ROR32(a, 13) ^ ROR32(a, 22);
102 maj = (a & b) ^ (a & c) ^ (b & c);
103 t2 = s0 + maj;
104 s1 = ROR32(e, 6) ^ ROR32(e, 11) ^ ROR32(e, 25);
105 ch = (e & f) ^ (~e & g);
106 t1 = h + s1 + ch + T_K[i] + p->w[i];
107
108 h = g;
109 g = f;
110 f = e;
111 e = d + t1;
112 d = c;
113 c = b;
114 b = a;
115 a = t1 + t2;
116 }
117
118 p->h[0] += a; p->h[1] += b; p->h[2] += c; p->h[3] += d;
119 p->h[4] += e; p->h[5] += f; p->h[6] += g; p->h[7] += h;
120
121 /* Next block */
122 p->inlen = 0;
123}
124
125static void sha256_chunk(struct sha256_ctx *p,
126 const uint8_t *s, unsigned len)
127{
128 p->len += len;
129
130 while (len)
131 {
132 unsigned l = 64 - p->inlen;
133
134 if (len < l)
135 l = len;
136
137 memcpy(p->in.u8 + p->inlen, s, l);
138
139 s += l;
140 p->inlen += l;
141 len -= l;
142
143 if (p->inlen == 64)
144 sha256_block(p);
145 }
146}
147
148static void sha256_final(struct sha256_ctx *p)
149{
150 uint64_t len;
151 p->in.u8[p->inlen++] = 0x80;
152
153 if (p->inlen > 56)
154 {
155 memset(p->in.u8 + p->inlen, 0, 64 - p->inlen);
156 sha256_block(p);
157 }
158
159 memset(p->in.u8 + p->inlen, 0, 56 - p->inlen);
160
161 len = p->len << 3;
162 store32be(p->in.u32 + 14, (uint32_t)(len >> 32));
163 store32be(p->in.u32 + 15, (uint32_t)len);
164 sha256_block(p);
165}
166
167static void sha256_subhash(struct sha256_ctx *p, uint32_t *t)
168{
169 unsigned i;
170 for (i = 0; i < 8; i++)
171 store32be(t++, p->h[i]);
172}
173
174/**
175 * sha256_hash:
176 * @s : Output.
177 * @in : Input.
178 * @size : Size of @s.
179 *
180 * Hashes SHA256 and outputs a human readable string.
181 **/
182void sha256_hash(char *s, const uint8_t *in, size_t size)
183{
184 unsigned i;
185 struct sha256_ctx sha;
186
187 union
188 {
189 uint32_t u32[8];
190 uint8_t u8[32];
191 } shahash;
192
193 sha256_init(&sha);
194 sha256_chunk(&sha, in, (unsigned)size);
195 sha256_final(&sha);
196 sha256_subhash(&sha, shahash.u32);
197
198 for (i = 0; i < 32; i++)
199 snprintf(s + 2 * i, 3, "%02x", (unsigned)shahash.u8[i]);
200}
201
202#ifndef HAVE_ZLIB
203/* Zlib CRC32. */
204static const uint32_t crc32_hash_table[256] = {
205 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
206 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
207 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
208 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
209 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
210 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
211 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
212 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
213 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
214 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
215 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
216 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
217 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
218 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
219 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
220 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
221 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
222 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
223 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
224 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
225 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
226 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
227 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
228 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
229 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
230 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
231 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
232 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
233 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
234 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
235 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
236 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
237 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
238 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
239 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
240 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
241 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
242 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
243 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
244 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
245 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
246 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
247 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
248};
249
250uint32_t crc32_adjust(uint32_t checksum, uint8_t input)
251{
252 return ((checksum >> 8) & 0x00ffffff) ^ crc32_hash_table[(checksum ^ input) & 0xff];
253}
254
255uint32_t crc32_calculate(const uint8_t *data, size_t length)
256{
257 size_t i;
258 uint32_t checksum = ~0;
259 for (i = 0; i < length; i++)
260 checksum = crc32_adjust(checksum, data[i]);
261 return ~checksum;
262}
263#endif
264
265/* SHA-1 implementation. */
266
267/*
268 * sha1.c
269 *
270 * Copyright (C) 1998, 2009
271 * Paul E. Jones <paulej@packetizer.com>
272 * All Rights Reserved
273 *
274 *****************************************************************************
275 * $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $
276 *****************************************************************************
277 *
278 * Description:
279 * This file implements the Secure Hashing Standard as defined
280 * in FIPS PUB 180-1 published April 17, 1995.
281 *
282 * The Secure Hashing Standard, which uses the Secure Hashing
283 * Algorithm (SHA), produces a 160-bit message digest for a
284 * given data stream. In theory, it is highly improbable that
285 * two messages will produce the same message digest. Therefore,
286 * this algorithm can serve as a means of providing a "fingerprint"
287 * for a message.
288 *
289 * Portability Issues:
290 * SHA-1 is defined in terms of 32-bit "words". This code was
291 * written with the expectation that the processor has at least
292 * a 32-bit machine word size. If the machine word size is larger,
293 * the code should still function properly. One caveat to that
294 * is that the input functions taking characters and character
295 * arrays assume that only 8 bits of information are stored in each
296 * character.
297 *
298 * Caveats:
299 * SHA-1 is designed to work with messages less than 2^64 bits
300 * long. Although SHA-1 allows a message digest to be generated for
301 * messages of any number of bits less than 2^64, this
302 * implementation only works with messages with a length that is a
303 * multiple of the size of an 8-bit character.
304 *
305 */
306
307/* Define the circular shift macro */
308#define SHA1CircularShift(bits,word) ((((word) << (bits)) & 0xFFFFFFFF) | ((word) >> (32-(bits))))
309
310struct sha1_context
311{
312 unsigned Message_Digest[5]; /* Message Digest (output) */
313
314 unsigned Length_Low; /* Message length in bits */
315 unsigned Length_High; /* Message length in bits */
316
317 unsigned char Message_Block[64]; /* 512-bit message blocks */
318 int Message_Block_Index; /* Index into message block array */
319
320 int Computed; /* Is the digest computed? */
321 int Corrupted; /* Is the message digest corruped? */
322};
323
324
325static void SHA1Reset(struct sha1_context *context)
326{
327 if (!context)
328 return;
329
330 context->Length_Low = 0;
331 context->Length_High = 0;
332 context->Message_Block_Index = 0;
333
334 context->Message_Digest[0] = 0x67452301;
335 context->Message_Digest[1] = 0xEFCDAB89;
336 context->Message_Digest[2] = 0x98BADCFE;
337 context->Message_Digest[3] = 0x10325476;
338 context->Message_Digest[4] = 0xC3D2E1F0;
339
340 context->Computed = 0;
341 context->Corrupted = 0;
342}
343
344static void SHA1ProcessMessageBlock(struct sha1_context *context)
345{
346 const unsigned K[] = /* Constants defined in SHA-1 */
347 {
348 0x5A827999,
349 0x6ED9EBA1,
350 0x8F1BBCDC,
351 0xCA62C1D6
352 };
353 int t; /* Loop counter */
354 unsigned temp; /* Temporary word value */
355 unsigned W[80]; /* Word sequence */
356 unsigned A, B, C, D, E; /* Word buffers */
357
358 /* Initialize the first 16 words in the array W */
359 for (t = 0; t < 16; t++)
360 {
361 W[t] = ((unsigned) context->Message_Block[t * 4]) << 24;
362 W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16;
363 W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8;
364 W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]);
365 }
366
367 for (t = 16; t < 80; t++)
368 W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
369
370 A = context->Message_Digest[0];
371 B = context->Message_Digest[1];
372 C = context->Message_Digest[2];
373 D = context->Message_Digest[3];
374 E = context->Message_Digest[4];
375
376 for (t = 0; t < 20; t++)
377 {
378 temp = SHA1CircularShift(5,A) +
379 ((B & C) | ((~B) & D)) + E + W[t] + K[0];
380 temp &= 0xFFFFFFFF;
381 E = D;
382 D = C;
383 C = SHA1CircularShift(30,B);
384 B = A;
385 A = temp;
386 }
387
388 for (t = 20; t < 40; t++)
389 {
390 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
391 temp &= 0xFFFFFFFF;
392 E = D;
393 D = C;
394 C = SHA1CircularShift(30,B);
395 B = A;
396 A = temp;
397 }
398
399 for (t = 40; t < 60; t++)
400 {
401 temp = SHA1CircularShift(5,A) +
402 ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
403 temp &= 0xFFFFFFFF;
404 E = D;
405 D = C;
406 C = SHA1CircularShift(30,B);
407 B = A;
408 A = temp;
409 }
410
411 for (t = 60; t < 80; t++)
412 {
413 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
414 temp &= 0xFFFFFFFF;
415 E = D;
416 D = C;
417 C = SHA1CircularShift(30,B);
418 B = A;
419 A = temp;
420 }
421
422 context->Message_Digest[0] =
423 (context->Message_Digest[0] + A) & 0xFFFFFFFF;
424 context->Message_Digest[1] =
425 (context->Message_Digest[1] + B) & 0xFFFFFFFF;
426 context->Message_Digest[2] =
427 (context->Message_Digest[2] + C) & 0xFFFFFFFF;
428 context->Message_Digest[3] =
429 (context->Message_Digest[3] + D) & 0xFFFFFFFF;
430 context->Message_Digest[4] =
431 (context->Message_Digest[4] + E) & 0xFFFFFFFF;
432
433 context->Message_Block_Index = 0;
434}
435
436static void SHA1PadMessage(struct sha1_context *context)
437{
438 if (!context)
439 return;
440
441 /*
442 * Check to see if the current message block is too small to hold
443 * the initial padding bits and length. If so, we will pad the
444 * block, process it, and then continue padding into a second
445 * block.
446 */
447 context->Message_Block[context->Message_Block_Index++] = 0x80;
448
449 if (context->Message_Block_Index > 55)
450 {
451 while (context->Message_Block_Index < 64)
452 context->Message_Block[context->Message_Block_Index++] = 0;
453
454 SHA1ProcessMessageBlock(context);
455 }
456
457 while (context->Message_Block_Index < 56)
458 context->Message_Block[context->Message_Block_Index++] = 0;
459
460 /* Store the message length as the last 8 octets */
461 context->Message_Block[56] = (context->Length_High >> 24) & 0xFF;
462 context->Message_Block[57] = (context->Length_High >> 16) & 0xFF;
463 context->Message_Block[58] = (context->Length_High >> 8) & 0xFF;
464 context->Message_Block[59] = (context->Length_High) & 0xFF;
465 context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF;
466 context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF;
467 context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF;
468 context->Message_Block[63] = (context->Length_Low) & 0xFF;
469
470 SHA1ProcessMessageBlock(context);
471}
472
473static int SHA1Result(struct sha1_context *context)
474{
475 if (context->Corrupted)
476 return 0;
477
478 if (!context->Computed)
479 {
480 SHA1PadMessage(context);
481 context->Computed = 1;
482 }
483
484 return 1;
485}
486
487static void SHA1Input(struct sha1_context *context,
488 const unsigned char *message_array,
489 unsigned length)
490{
491 if (!length)
492 return;
493
494 if (context->Computed || context->Corrupted)
495 {
496 context->Corrupted = 1;
497 return;
498 }
499
500 while (length-- && !context->Corrupted)
501 {
502 context->Message_Block[context->Message_Block_Index++] =
503 (*message_array & 0xFF);
504
505 context->Length_Low += 8;
506 /* Force it to 32 bits */
507 context->Length_Low &= 0xFFFFFFFF;
508 if (context->Length_Low == 0)
509 {
510 context->Length_High++;
511 /* Force it to 32 bits */
512 context->Length_High &= 0xFFFFFFFF;
513 if (context->Length_High == 0)
514 context->Corrupted = 1; /* Message is too long */
515 }
516
517 if (context->Message_Block_Index == 64)
518 SHA1ProcessMessageBlock(context);
519
520 message_array++;
521 }
522}
523
524int sha1_calculate(const char *path, char *result)
525{
526 struct sha1_context sha;
527 unsigned char buff[4096];
528 int rv = 1;
529 RFILE *fd = filestream_open(path,
530 RETRO_VFS_FILE_ACCESS_READ,
531 RETRO_VFS_FILE_ACCESS_HINT_NONE);
532
533 if (!fd)
534 goto error;
535
536 buff[0] = '\0';
537
538 SHA1Reset(&sha);
539
540 do
541 {
542 rv = (int)filestream_read(fd, buff, 4096);
543 if (rv < 0)
544 goto error;
545
546 SHA1Input(&sha, buff, rv);
547 } while (rv);
548
549 if (!SHA1Result(&sha))
550 goto error;
551
552 sprintf(result, "%08X%08X%08X%08X%08X",
553 sha.Message_Digest[0],
554 sha.Message_Digest[1],
555 sha.Message_Digest[2],
556 sha.Message_Digest[3], sha.Message_Digest[4]);
557
558 filestream_close(fd);
559 return 0;
560
561error:
562 if (fd)
563 filestream_close(fd);
564 return -1;
565}
566
567uint32_t djb2_calculate(const char *str)
568{
569 const unsigned char *aux = (const unsigned char*)str;
570 uint32_t hash = 5381;
571
572 while ( *aux )
573 hash = ( hash << 5 ) + hash + *aux++;
574
575 return hash;
576}