aboutsummaryrefslogtreecommitdiff
path: root/tools/XBMCTex/sha.c
blob: 809c4235cd540ecf08c341b1a15dd85f6c9bf16e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#include <string.h>
#ifdef _LINUX
#include <stdint.h>
#else
#include "stdint_win.h"
#endif

typedef unsigned long u32;
typedef unsigned char u8;

#ifdef _LINUX
#include <string.h>
#define __forceinline inline
#define __int64 int64_t
#endif

__forceinline static u32 rol(u32 x, u8 n)
{
	return (x << n) | (x >> (32-n));
}

static void bswapcpy(void* dst, const void* src, u32 n)
{
  uint32_t d, b0, b1, b2, b3;
  uint32_t *nDst = (uint32_t *)dst;
  uint32_t *nSrc = (uint32_t *)src;
  n >>= 2;
  while (n != 0)
  {
    d = *nSrc;
    b0 = d >> 24;
    b1 = (d >> 8) & 0x0000ff00;
    b2 = (d << 8) & 0x00ff0000;
    b3 = (d << 24);
    *nDst = b3 | b2 | b1 | b0;
    --n;
    ++nSrc;
    ++nDst;
  }
}

void SHA1(const u8* buf, u32 len, u8 hash[20])
{
	u32 a, b, c, d, e;
	u32 h[5] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 };
	u32 w[80];
	u32 n = len;
	int t;
	int done = 0;

	while (done != 2)
	{
		if (n >= 64)
		{
			bswapcpy(w, buf, 64);
			buf += 64;
			n -= 64;
		}
		else
		{
			u8 tmpbuf[64];
			memcpy(tmpbuf, buf, n);
			memset(tmpbuf+n, 0, 64-n);
			if (!done)
				tmpbuf[n] = 0x80;
			bswapcpy(w, tmpbuf, 64);
			if (n <= 55)
			{
				u32 bitlen = len * 8;
				w[14] = *(((u32*)&bitlen)+1);
				w[15] = *((u32*)&bitlen);
				done = 2;
			}
			else
				done = 1;
			n = 0;
		}

		for (t = 16; t < 80; ++t)
		{
			w[t] = rol(w[t-3] ^ w[t-8] ^ w[t-14] ^ w[t-16], 1);
		}

		a = h[0]; b = h[1]; c = h[2]; d = h[3]; e = h[4];

		for (t = 0; t < 20; ++t)
		{
			u32 temp = rol(a, 5) + ((b & c) | ((~b) & d)) + e + w[t] + 0x5A827999;
			e = d; d = c; c = rol(b, 30); b = a; a = temp;
		}
		for ( ; t < 40; ++t)
		{
			u32 temp = rol(a, 5) + (b ^ c ^ d) + e + w[t] + 0x6ED9EBA1;
			e = d; d = c; c = rol(b, 30); b = a; a = temp;
		}
		for ( ; t < 60; ++t)
		{
			u32 temp = rol(a, 5) + ((b & c) | (b & d) | (c & d)) + e + w[t] + 0x8F1BBCDC;
			e = d; d = c; c = rol(b, 30); b = a; a = temp;
		}
		for ( ; t < 80; ++t)
		{
			u32 temp = rol(a, 5) + (b ^ c ^ d) + e + w[t] + 0xCA62C1D6;
			e = d; d = c; c = rol(b, 30); b = a; a = temp;
		}

		h[0] += a; h[1] += b; h[2] += c; h[3] += d; h[4] += e;
	}

	bswapcpy(hash, h, 20);
}