ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
sha1.c
Go to the documentation of this file.
1/* $OpenBSD: sha1.c,v 1.11 2014/12/28 10:04:35 tedu Exp $ */
2
3/*
4 * SHA-1 in C
5 * By Steve Reid <steve@edmweb.com>
6 * 100% Public Domain
7 *
8 * Test Vectors (from FIPS PUB 180-1)
9 * "abc"
10 * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
11 * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
12 * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
13 * A million repetitions of "a"
14 * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
15 */
16
17/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
18/* #define SHA1HANDSOFF * Copies data before messing with it. */
19
20#define SHA1HANDSOFF
21
22#include <ascii-chat/crypto/sha1.h>
23
24/* Portable endianness detection */
25#if !defined(BYTE_ORDER)
26#if defined(__BYTE_ORDER__)
27#define BYTE_ORDER __BYTE_ORDER__
28#define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
29#define BIG_ENDIAN __ORDER_BIG_ENDIAN__
30#else
31/* Assume little endian for x86/x86_64/ARM (most common) */
32#define BYTE_ORDER 1234
33#define LITTLE_ENDIAN 1234
34#define BIG_ENDIAN 4321
35#endif
36#endif
37
38#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
39
40/* blk0() and blk() perform the initial expand. */
41/* I got the idea of expanding during the round function from SSLeay */
42#if BYTE_ORDER == LITTLE_ENDIAN
43#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | (rol(block->l[i], 8) & 0x00FF00FF))
44#else
45#define blk0(i) block->l[i]
46#endif
47#define blk(i) \
48 (block->l[i & 15] = \
49 rol(block->l[(i + 13) & 15] ^ block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
50
51/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
52#define R0(v, w, x, y, z, i) \
53 z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
54 w = rol(w, 30);
55#define R1(v, w, x, y, z, i) \
56 z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
57 w = rol(w, 30);
58#define R2(v, w, x, y, z, i) \
59 z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \
60 w = rol(w, 30);
61#define R3(v, w, x, y, z, i) \
62 z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
63 w = rol(w, 30);
64#define R4(v, w, x, y, z, i) \
65 z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
66 w = rol(w, 30);
67
68/* Hash a single 512-bit block. This is the core of the algorithm. */
69
70void SHA1Transform(uint32_t state[5], const unsigned char buffer[SHA1_BLOCK_LENGTH]) {
71 uint32_t a, b, c, d, e;
72 typedef union {
73 unsigned char c[64];
74 uint32_t l[16];
75 } CHAR64LONG16;
76 CHAR64LONG16 *block;
77#ifdef SHA1HANDSOFF
78 unsigned char workspace[SHA1_BLOCK_LENGTH];
79
80 block = (CHAR64LONG16 *)workspace;
81 memcpy(block, buffer, SHA1_BLOCK_LENGTH);
82#else
83 block = (CHAR64LONG16 *)buffer;
84#endif
85 /* Copy context->state[] to working vars */
86 a = state[0];
87 b = state[1];
88 c = state[2];
89 d = state[3];
90 e = state[4];
91
92 /* 4 rounds of 20 operations each. Loop unrolled. */
93 R0(a, b, c, d, e, 0);
94 R0(e, a, b, c, d, 1);
95 R0(d, e, a, b, c, 2);
96 R0(c, d, e, a, b, 3);
97 R0(b, c, d, e, a, 4);
98 R0(a, b, c, d, e, 5);
99 R0(e, a, b, c, d, 6);
100 R0(d, e, a, b, c, 7);
101 R0(c, d, e, a, b, 8);
102 R0(b, c, d, e, a, 9);
103 R0(a, b, c, d, e, 10);
104 R0(e, a, b, c, d, 11);
105 R0(d, e, a, b, c, 12);
106 R0(c, d, e, a, b, 13);
107 R0(b, c, d, e, a, 14);
108 R0(a, b, c, d, e, 15);
109 R1(e, a, b, c, d, 16);
110 R1(d, e, a, b, c, 17);
111 R1(c, d, e, a, b, 18);
112 R1(b, c, d, e, a, 19);
113 R2(a, b, c, d, e, 20);
114 R2(e, a, b, c, d, 21);
115 R2(d, e, a, b, c, 22);
116 R2(c, d, e, a, b, 23);
117 R2(b, c, d, e, a, 24);
118 R2(a, b, c, d, e, 25);
119 R2(e, a, b, c, d, 26);
120 R2(d, e, a, b, c, 27);
121 R2(c, d, e, a, b, 28);
122 R2(b, c, d, e, a, 29);
123 R2(a, b, c, d, e, 30);
124 R2(e, a, b, c, d, 31);
125 R2(d, e, a, b, c, 32);
126 R2(c, d, e, a, b, 33);
127 R2(b, c, d, e, a, 34);
128 R2(a, b, c, d, e, 35);
129 R2(e, a, b, c, d, 36);
130 R2(d, e, a, b, c, 37);
131 R2(c, d, e, a, b, 38);
132 R2(b, c, d, e, a, 39);
133 R3(a, b, c, d, e, 40);
134 R3(e, a, b, c, d, 41);
135 R3(d, e, a, b, c, 42);
136 R3(c, d, e, a, b, 43);
137 R3(b, c, d, e, a, 44);
138 R3(a, b, c, d, e, 45);
139 R3(e, a, b, c, d, 46);
140 R3(d, e, a, b, c, 47);
141 R3(c, d, e, a, b, 48);
142 R3(b, c, d, e, a, 49);
143 R3(a, b, c, d, e, 50);
144 R3(e, a, b, c, d, 51);
145 R3(d, e, a, b, c, 52);
146 R3(c, d, e, a, b, 53);
147 R3(b, c, d, e, a, 54);
148 R3(a, b, c, d, e, 55);
149 R3(e, a, b, c, d, 56);
150 R3(d, e, a, b, c, 57);
151 R3(c, d, e, a, b, 58);
152 R3(b, c, d, e, a, 59);
153 R4(a, b, c, d, e, 60);
154 R4(e, a, b, c, d, 61);
155 R4(d, e, a, b, c, 62);
156 R4(c, d, e, a, b, 63);
157 R4(b, c, d, e, a, 64);
158 R4(a, b, c, d, e, 65);
159 R4(e, a, b, c, d, 66);
160 R4(d, e, a, b, c, 67);
161 R4(c, d, e, a, b, 68);
162 R4(b, c, d, e, a, 69);
163 R4(a, b, c, d, e, 70);
164 R4(e, a, b, c, d, 71);
165 R4(d, e, a, b, c, 72);
166 R4(c, d, e, a, b, 73);
167 R4(b, c, d, e, a, 74);
168 R4(a, b, c, d, e, 75);
169 R4(e, a, b, c, d, 76);
170 R4(d, e, a, b, c, 77);
171 R4(c, d, e, a, b, 78);
172 R4(b, c, d, e, a, 79);
173
174 /* Add the working vars back into context.state[] */
175 state[0] += a;
176 state[1] += b;
177 state[2] += c;
178 state[3] += d;
179 state[4] += e;
180 /* Wipe variables */
181 a = b = c = d = e = 0;
182}
183
184/* SHA1Init - Initialize new context */
185
186void SHA1Init(SHA1_CTX *context) {
187 /* SHA1 initialization constants */
188 context->count = 0;
189 context->state[0] = 0x67452301;
190 context->state[1] = 0xEFCDAB89;
191 context->state[2] = 0x98BADCFE;
192 context->state[3] = 0x10325476;
193 context->state[4] = 0xC3D2E1F0;
194}
195
196/* Run your data through this. */
197
198void SHA1Update(SHA1_CTX *context, const void *dataptr, unsigned int len) {
199 const uint8_t *data = dataptr;
200 unsigned int i;
201 unsigned int j;
202
203 j = (uint32_t)((context->count >> 3) & 63);
204 context->count += (len << 3);
205 if ((j + len) > 63) {
206 memcpy(&context->buffer[j], data, (i = 64 - j));
207 SHA1Transform(context->state, context->buffer);
208 for (; i + 63 < len; i += 64) {
209 SHA1Transform(context->state, &data[i]);
210 }
211 j = 0;
212 } else
213 i = 0;
214 memcpy(&context->buffer[j], &data[i], len - i);
215}
216
217/* Add padding and return the message digest. */
218
219void SHA1Final(unsigned char digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context) {
220 unsigned int i;
221 unsigned char finalcount[8];
222
223 for (i = 0; i < 8; i++) {
224 finalcount[i] = (unsigned char)((context->count >> ((7 - (i & 7)) * 8)) & 255); /* Endian independent */
225 }
226 SHA1Update(context, "\200", 1);
227 while ((context->count & 504) != 448) {
228 SHA1Update(context, "\0", 1);
229 }
230 SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
231
232 for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
233 digest[i] = (unsigned char)((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
234 }
235 memset(&finalcount, 0, sizeof(finalcount));
236 memset(context, 0, sizeof(*context));
237}
void SHA1Update(SHA1_CTX *context, const void *dataptr, unsigned int len)
Definition sha1.c:198
void SHA1Init(SHA1_CTX *context)
Definition sha1.c:186
#define R1(v, w, x, y, z, i)
Definition sha1.c:55
#define R2(v, w, x, y, z, i)
Definition sha1.c:58
#define R0(v, w, x, y, z, i)
Definition sha1.c:52
void SHA1Transform(uint32_t state[5], const unsigned char buffer[SHA1_BLOCK_LENGTH])
Definition sha1.c:70
#define R3(v, w, x, y, z, i)
Definition sha1.c:61
void SHA1Final(unsigned char digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context)
Definition sha1.c:219
#define R4(v, w, x, y, z, i)
Definition sha1.c:64