Browse Source

added sha1 cryptographic hash function

SBird1337 7 years ago
parent
commit
5e99486e6e
2 changed files with 241 additions and 0 deletions
  1. 217
    0
      src/crypto/sha1.c
  2. 24
    0
      src/include/sha1.h

+ 217
- 0
src/crypto/sha1.c View File

@@ -0,0 +1,217 @@
1
+/*
2
+SHA-1 in C
3
+By Steve Reid <steve@edmweb.com>
4
+100% Public Domain
5
+Test Vectors (from FIPS PUB 180-1)
6
+"abc"
7
+  A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
8
+"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
9
+  84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
10
+A million repetitions of "a"
11
+  34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
12
+*/
13
+
14
+#include <stdint.h>
15
+#include <pokeagb/pokeagb.h>
16
+#include <sha1.h>
17
+
18
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
19
+#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | (rol(block->l[i], 8) & 0x00FF00FF))
20
+#define blk(i)                                                                                                         \
21
+    (block->l[i & 15] =                                                                                                \
22
+         rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
23
+
24
+/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
25
+#define R0(v, w, x, y, z, i)                                                                                           \
26
+    z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5);                                                       \
27
+    w = rol(w, 30);
28
+
29
+#define R1(v, w, x, y, z, i)                                                                                           \
30
+    z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5);                                                        \
31
+    w = rol(w, 30);
32
+
33
+#define R2(v, w, x, y, z, i)                                                                                           \
34
+    z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5);                                                                \
35
+    w = rol(w, 30);
36
+
37
+#define R3(v, w, x, y, z, i)                                                                                           \
38
+    z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5);                                                  \
39
+    w = rol(w, 30);
40
+
41
+#define R4(v, w, x, y, z, i)                                                                                           \
42
+    z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5);                                                                \
43
+    w = rol(w, 30);
44
+
45
+void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]) {
46
+    uint32_t a, b, c, d, e;
47
+
48
+    typedef union {
49
+        unsigned char c[64];
50
+        uint32_t l[16];
51
+    } CHAR64LONG16;
52
+
53
+    CHAR64LONG16 block[1]; /* use array to appear as a pointer */
54
+    memcpy(block, buffer, 64);
55
+
56
+    /* Copy context->state[] to working vars */
57
+    a = state[0];
58
+    b = state[1];
59
+    c = state[2];
60
+    d = state[3];
61
+    e = state[4];
62
+    /* 4 rounds of 20 operations each. Loop unrolled. */
63
+    R0(a, b, c, d, e, 0);
64
+    R0(e, a, b, c, d, 1);
65
+    R0(d, e, a, b, c, 2);
66
+    R0(c, d, e, a, b, 3);
67
+    R0(b, c, d, e, a, 4);
68
+    R0(a, b, c, d, e, 5);
69
+    R0(e, a, b, c, d, 6);
70
+    R0(d, e, a, b, c, 7);
71
+    R0(c, d, e, a, b, 8);
72
+    R0(b, c, d, e, a, 9);
73
+    R0(a, b, c, d, e, 10);
74
+    R0(e, a, b, c, d, 11);
75
+    R0(d, e, a, b, c, 12);
76
+    R0(c, d, e, a, b, 13);
77
+    R0(b, c, d, e, a, 14);
78
+    R0(a, b, c, d, e, 15);
79
+    R1(e, a, b, c, d, 16);
80
+    R1(d, e, a, b, c, 17);
81
+    R1(c, d, e, a, b, 18);
82
+    R1(b, c, d, e, a, 19);
83
+    R2(a, b, c, d, e, 20);
84
+    R2(e, a, b, c, d, 21);
85
+    R2(d, e, a, b, c, 22);
86
+    R2(c, d, e, a, b, 23);
87
+    R2(b, c, d, e, a, 24);
88
+    R2(a, b, c, d, e, 25);
89
+    R2(e, a, b, c, d, 26);
90
+    R2(d, e, a, b, c, 27);
91
+    R2(c, d, e, a, b, 28);
92
+    R2(b, c, d, e, a, 29);
93
+    R2(a, b, c, d, e, 30);
94
+    R2(e, a, b, c, d, 31);
95
+    R2(d, e, a, b, c, 32);
96
+    R2(c, d, e, a, b, 33);
97
+    R2(b, c, d, e, a, 34);
98
+    R2(a, b, c, d, e, 35);
99
+    R2(e, a, b, c, d, 36);
100
+    R2(d, e, a, b, c, 37);
101
+    R2(c, d, e, a, b, 38);
102
+    R2(b, c, d, e, a, 39);
103
+    R3(a, b, c, d, e, 40);
104
+    R3(e, a, b, c, d, 41);
105
+    R3(d, e, a, b, c, 42);
106
+    R3(c, d, e, a, b, 43);
107
+    R3(b, c, d, e, a, 44);
108
+    R3(a, b, c, d, e, 45);
109
+    R3(e, a, b, c, d, 46);
110
+    R3(d, e, a, b, c, 47);
111
+    R3(c, d, e, a, b, 48);
112
+    R3(b, c, d, e, a, 49);
113
+    R3(a, b, c, d, e, 50);
114
+    R3(e, a, b, c, d, 51);
115
+    R3(d, e, a, b, c, 52);
116
+    R3(c, d, e, a, b, 53);
117
+    R3(b, c, d, e, a, 54);
118
+    R3(a, b, c, d, e, 55);
119
+    R3(e, a, b, c, d, 56);
120
+    R3(d, e, a, b, c, 57);
121
+    R3(c, d, e, a, b, 58);
122
+    R3(b, c, d, e, a, 59);
123
+    R4(a, b, c, d, e, 60);
124
+    R4(e, a, b, c, d, 61);
125
+    R4(d, e, a, b, c, 62);
126
+    R4(c, d, e, a, b, 63);
127
+    R4(b, c, d, e, a, 64);
128
+    R4(a, b, c, d, e, 65);
129
+    R4(e, a, b, c, d, 66);
130
+    R4(d, e, a, b, c, 67);
131
+    R4(c, d, e, a, b, 68);
132
+    R4(b, c, d, e, a, 69);
133
+    R4(a, b, c, d, e, 70);
134
+    R4(e, a, b, c, d, 71);
135
+    R4(d, e, a, b, c, 72);
136
+    R4(c, d, e, a, b, 73);
137
+    R4(b, c, d, e, a, 74);
138
+    R4(a, b, c, d, e, 75);
139
+    R4(e, a, b, c, d, 76);
140
+    R4(d, e, a, b, c, 77);
141
+    R4(c, d, e, a, b, 78);
142
+    R4(b, c, d, e, a, 79);
143
+    /* Add the working vars back into context.state[] */
144
+    state[0] += a;
145
+    state[1] += b;
146
+    state[2] += c;
147
+    state[3] += d;
148
+    state[4] += e;
149
+    /* Wipe variables */
150
+    a = b = c = d = e = 0;
151
+
152
+    memset(block, '\0', sizeof(block));
153
+}
154
+
155
+void SHA1Init(SHA1_CTX *context) {
156
+    /* SHA1 initialization constants */
157
+    context->state[0] = 0x67452301;
158
+    context->state[1] = 0xEFCDAB89;
159
+    context->state[2] = 0x98BADCFE;
160
+    context->state[3] = 0x10325476;
161
+    context->state[4] = 0xC3D2E1F0;
162
+    context->count[0] = context->count[1] = 0;
163
+}
164
+
165
+void SHA1Update(SHA1_CTX *context, const unsigned char *data, uint32_t len) {
166
+    uint32_t i;
167
+    uint32_t j;
168
+    j = context->count[0];
169
+    if ((context->count[0] += len << 3) < j)
170
+        context->count[1]++;
171
+    context->count[1] += (len >> 29);
172
+    j = (j >> 3) & 63;
173
+    if ((j + len) > 63) {
174
+        memcpy(&context->buffer[j], data, (i = 64 - j));
175
+        SHA1Transform(context->state, context->buffer);
176
+        for (; i + 63 < len; i += 64) {
177
+            SHA1Transform(context->state, &data[i]);
178
+        }
179
+        j = 0;
180
+    } else
181
+        i = 0;
182
+    memcpy(&context->buffer[j], &data[i], len - i);
183
+}
184
+
185
+void SHA1Final(unsigned char digest[20], SHA1_CTX *context) {
186
+    unsigned i;
187
+    unsigned char finalcount[8];
188
+    unsigned char c;
189
+    for (i = 0; i < 8; i++) {
190
+        finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255);
191
+    }
192
+
193
+    c = 0200;
194
+    SHA1Update(context, &c, 1);
195
+    while ((context->count[0] & 504) != 448) {
196
+        c = 0000;
197
+        SHA1Update(context, &c, 1);
198
+    }
199
+    SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
200
+    for (i = 0; i < 20; i++) {
201
+        digest[i] = (unsigned char)((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
202
+    }
203
+    /* Wipe variables */
204
+    memset(context, '\0', sizeof(*context));
205
+    memset(&finalcount, '\0', sizeof(finalcount));
206
+}
207
+
208
+void SHA1(char *hash_out, const char *str, uint32_t len) {
209
+    SHA1_CTX ctx;
210
+    uint32_t ii;
211
+
212
+    SHA1Init(&ctx);
213
+    for (ii = 0; ii < len; ii += 1)
214
+        SHA1Update(&ctx, (const unsigned char *)str + ii, 1);
215
+    SHA1Final((unsigned char *)hash_out, &ctx);
216
+    hash_out[20] = '\0';
217
+}

+ 24
- 0
src/include/sha1.h View File

@@ -0,0 +1,24 @@
1
+#ifndef SHA1_H
2
+#define SHA1_H
3
+
4
+/*
5
+   SHA-1 in C
6
+   By Steve Reid <steve@edmweb.com>
7
+   100% Public Domain
8
+ */
9
+
10
+#include <stdint.h>
11
+
12
+typedef struct {
13
+    uint32_t state[5];
14
+    uint32_t count[2];
15
+    unsigned char buffer[64];
16
+} SHA1_CTX;
17
+
18
+void SHA1Transform(uint32_t state[5], const unsigned char buffer[64]);
19
+void SHA1Init(SHA1_CTX *context);
20
+void SHA1Update(SHA1_CTX *context, const unsigned char *data, uint32_t len);
21
+void SHA1Final(unsigned char digest[20], SHA1_CTX *context);
22
+void SHA1(char *hash_out, const char *str, uint32_t len);
23
+
24
+#endif /* SHA1_H */