Skip to content

Latest commit

 

History

History
217 lines (185 loc) · 6.95 KB

sha1.c

File metadata and controls

217 lines (185 loc) · 6.95 KB
 
Dec 18, 2013
Dec 18, 2013
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
/* $OpenBSD: sha1.c,v 1.9 2011/01/11 15:50:40 deraadt Exp $ */
/*
* SHA-1 in C
* By Steve Reid <steve@edmweb.com>
* 100% Public Domain
*
* Test Vectors (from FIPS PUB 180-1)
* "abc"
* A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
* "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
* 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
* A million repetitions of "a"
* 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
*/
/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
/* #define SHA1HANDSOFF * Copies data before messing with it. */
#define SHA1HANDSOFF
#include <string.h>
#include <sys/param.h>
//#include <sys/systm.h>
#include "sha1.h"
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
/* blk0() and blk() perform the initial expand. */
/* I got the idea of expanding during the round function from SSLeay */
#if PLATFORM_LITTLEENDIAN
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|(rol(block->l[i],8)&0x00FF00FF))
#else
#define blk0(i) block->l[i]
#endif
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
^block->l[(i+2)&15]^block->l[i&15],1))
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
/* Hash a single 512-bit block. This is the core of the algorithm. */
void
Jun 18, 2017
Jun 18, 2017
51
SHA1Transform(uint32_t state[5], const uint8_t buffer[SHA1_BLOCK_LENGTH])
Dec 18, 2013
Dec 18, 2013
52
{
Jun 18, 2017
Jun 18, 2017
53
uint32_t a, b, c, d, e;
Dec 18, 2013
Dec 18, 2013
54
typedef union {
Jun 18, 2017
Jun 18, 2017
55
56
uint8_t c[64];
uint32_t l[16];
Dec 18, 2013
Dec 18, 2013
57
58
59
} CHAR64LONG16;
CHAR64LONG16* block;
#ifdef SHA1HANDSOFF
Jun 18, 2017
Jun 18, 2017
60
uint8_t workspace[SHA1_BLOCK_LENGTH];
Dec 18, 2013
Dec 18, 2013
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
112
113
114
115
116
117
118
119
120
121
122
123
124
block = (CHAR64LONG16 *)workspace;
memcpy(block, buffer, SHA1_BLOCK_LENGTH);
#else
block = (CHAR64LONG16 *)buffer;
#endif
/* Copy context->state[] to working vars */
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
/* 4 rounds of 20 operations each. Loop unrolled. */
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
/* Add the working vars back into context.state[] */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
state[4] += e;
/* Wipe variables */
a = b = c = d = e = 0;
}
/* SHA1Init - Initialize new context */
void
SHA1Init(SHA1_CTX *context)
{
/* SHA1 initialization constants */
context->count = 0;
context->state[0] = 0x67452301;
context->state[1] = 0xEFCDAB89;
context->state[2] = 0x98BADCFE;
context->state[3] = 0x10325476;
context->state[4] = 0xC3D2E1F0;
}
/* Run your data through this. */
void
Jun 18, 2017
Jun 18, 2017
125
SHA1Update(SHA1_CTX *context, const uint8_t *data, const uint32_t len)
Dec 18, 2013
Dec 18, 2013
126
{
Jun 18, 2017
Jun 18, 2017
127
128
uint32_t i;
uint32_t j;
Dec 18, 2013
Dec 18, 2013
129
Jun 18, 2017
Jun 18, 2017
130
j = (uint32_t)((context->count >> 3) & 63);
Dec 18, 2013
Dec 18, 2013
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
context->count += (len << 3);
if ((j + len) > 63) {
memcpy(&context->buffer[j], data, (i = 64 - j));
SHA1Transform(context->state, context->buffer);
for ( ; i + 63 < len; i += 64) {
SHA1Transform(context->state, &data[i]);
}
j = 0;
}
else i = 0;
memcpy(&context->buffer[j], &data[i], len - i);
}
/* Add padding and return the message digest. */
void
Jun 18, 2017
Jun 18, 2017
148
SHA1Final(uint8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context)
Dec 18, 2013
Dec 18, 2013
149
150
{
unsigned int i;
Jun 18, 2017
Jun 18, 2017
151
uint8_t finalcount[8];
Dec 18, 2013
Dec 18, 2013
152
153
for (i = 0; i < 8; i++) {
Jun 18, 2017
Jun 18, 2017
154
finalcount[i] = (uint8_t)((context->count >>
Dec 18, 2013
Dec 18, 2013
155
156
((7 - (i & 7)) * 8)) & 255); /* Endian independent */
}
Jun 18, 2017
Jun 18, 2017
157
SHA1Update(context, (uint8_t *)"\200", 1);
Dec 18, 2013
Dec 18, 2013
158
while ((context->count & 504) != 448) {
Jun 18, 2017
Jun 18, 2017
159
SHA1Update(context, (uint8_t *)"\0", 1);
Dec 18, 2013
Dec 18, 2013
160
161
162
163
164
}
SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
if (digest)
for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
Jun 18, 2017
Jun 18, 2017
165
digest[i] = (uint8_t)((context->state[i >> 2] >>
Dec 18, 2013
Dec 18, 2013
166
167
168
169
170
171
172
173
174
175
176
177
178
179
((3 - (i & 3)) * 8)) & 255);
}
memset(finalcount, '\0', 8);
#if 0 /* We want to use this for "keyfill" */
/* Wipe variables */
i = 0;
bzero(context->buffer, 64);
bzero(context->state, 20);
bzero(context->count, 8);
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
SHA1Transform(context->state, context->buffer);
#endif
#endif
}
Jun 18, 2017
Jun 18, 2017
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/* https://www.ietf.org/rfc/rfc2104.txt */
void SHA1Hmac(const uint8_t *key, const uint32_t keylen, const uint8_t *msg, const uint32_t msglen, uint8_t digest[SHA1_DIGEST_LENGTH])
{
SHA1_CTX sha1;
uint8_t block[64]; // 512 bits.
uint8_t xori[sizeof (block)];
uint8_t xoro[sizeof (block)];
int i;
memset(block, '\0', sizeof (block));
if (keylen <= sizeof (block)) {
memcpy(block, key, keylen);
} else {
/* SHA-1 the key itself to shrink it down. */
SHA1Init(&sha1);
SHA1Update(&sha1, key, keylen);
SHA1Final(block, &sha1);
}
for (i = 0; i < sizeof (block); i++) {
const uint8_t b = block[i];
xori[i] = b ^ 0x36; /* XOR block vs ipad value */
xoro[i] = b ^ 0x5C; /* XOR block vs opad value */
}
SHA1Init(&sha1);
SHA1Update(&sha1, xori, sizeof (xori));
SHA1Update(&sha1, msg, msglen);
SHA1Final(block, &sha1);
SHA1Init(&sha1);
SHA1Update(&sha1, xoro, sizeof (xoro));
SHA1Update(&sha1, block, SHA1_DIGEST_LENGTH);
SHA1Final(digest, &sha1);
}