]> FriiDump Source - friidump.git/blob - libfriidump/xbox_ref/xbox_ref_sha1.c
FriiDump 0.5.3.15: close XGD1 geometry and lead-in capture
[friidump.git] / libfriidump / xbox_ref / xbox_ref_sha1.c
1 #include "sha1.h"
2 #include <string.h>
3
4 #define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
5
6 static void SHA1_Transform(SHA1_CTX* ctx, const uint8_t data[64]) {
7     uint32_t a, b, c, d, e, i, j, t, m[80];
8
9     for (i = 0, j = 0; i < 16; ++i, j += 4)
10         m[i] = (data[j] << 24) | (data[j+1] << 16) | (data[j+2] << 8) | (data[j+3]);
11     for ( ; i < 80; ++i)
12         m[i] = ROTLEFT(m[i-3] ^ m[i-8] ^ m[i-14] ^ m[i-16], 1);
13
14     a = ctx->state[0];
15     b = ctx->state[1];
16     c = ctx->state[2];
17     d = ctx->state[3];
18     e = ctx->state[4];
19
20     for (i = 0; i < 80; ++i) {
21         if (i < 20)
22             t = ROTLEFT(a,5) + ((b & c) | (~b & d)) + e + m[i] + 0x5A827999;
23         else if (i < 40)
24             t = ROTLEFT(a,5) + (b ^ c ^ d) + e + m[i] + 0x6ED9EBA1;
25         else if (i < 60)
26             t = ROTLEFT(a,5) + ((b & c) | (b & d) | (c & d)) + e + m[i] + 0x8F1BBCDC;
27         else
28             t = ROTLEFT(a,5) + (b ^ c ^ d) + e + m[i] + 0xCA62C1D6;
29
30         e = d;
31         d = c;
32         c = ROTLEFT(b,30);
33         b = a;
34         a = t;
35     }
36
37     ctx->state[0] += a;
38     ctx->state[1] += b;
39     ctx->state[2] += c;
40     ctx->state[3] += d;
41     ctx->state[4] += e;
42 }
43
44 void SHA1_Init(SHA1_CTX* ctx) {
45     ctx->state[0] = 0x67452301;
46     ctx->state[1] = 0xEFCDAB89;
47     ctx->state[2] = 0x98BADCFE;
48     ctx->state[3] = 0x10325476;
49     ctx->state[4] = 0xC3D2E1F0;
50     ctx->count[0] = ctx->count[1] = 0;
51 }
52
53 void SHA1_Update(SHA1_CTX* ctx, const uint8_t* data, uint32_t len) {
54     uint32_t i, j;
55
56     j = (ctx->count[0] >> 3) & 63;
57     if ((ctx->count[0] += len << 3) < (len << 3))
58         ctx->count[1]++;
59     ctx->count[1] += (len >> 29);
60
61     if ((j + len) > 63) {
62         memcpy(&ctx->buffer[j], data, (i = 64 - j));
63         SHA1_Transform(ctx, ctx->buffer);
64         for ( ; i + 63 < len; i += 64)
65             SHA1_Transform(ctx, &data[i]);
66         j = 0;
67     } else {
68         i = 0;
69     }
70     memcpy(&ctx->buffer[j], &data[i], len - i);
71 }
72
73 void SHA1_Final(uint8_t digest[20], SHA1_CTX* ctx) {
74     uint8_t finalcount[8];
75     uint8_t c;
76     uint32_t i;
77
78     for (i = 0; i < 8; i++)
79         finalcount[i] = (uint8_t)((ctx->count[(i >= 4 ? 0 : 1)]
80                                   >> ((3 - (i & 3)) * 8)) & 255);
81
82     c = 0x80;
83     SHA1_Update(ctx, &c, 1);
84     while ((ctx->count[0] & 504) != 448) {
85         c = 0x00;
86         SHA1_Update(ctx, &c, 1);
87     }
88
89     SHA1_Update(ctx, finalcount, 8);
90
91     for (i = 0; i < 20; i++)
92         digest[i] = (uint8_t)((ctx->state[i>>2] >> ((3 - (i & 3)) * 8)) & 255);
93
94     memset(ctx, 0, sizeof(*ctx));
95 }