line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
/* |
2
|
|
|
|
|
|
|
* modified for ldns by Jelte Jansen, original taken from OpenBSD: |
3
|
|
|
|
|
|
|
* |
4
|
|
|
|
|
|
|
* SHA-1 in C |
5
|
|
|
|
|
|
|
* By Steve Reid |
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
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
#include |
20
|
|
|
|
|
|
|
#include |
21
|
|
|
|
|
|
|
#include |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
#define SHA1HANDSOFF 1 /* Copies data before messing with it. */ |
24
|
|
|
|
|
|
|
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
/* blk0() and blk() perform the initial expand. */ |
27
|
|
|
|
|
|
|
/* I got the idea of expanding during the round function from SSLeay */ |
28
|
|
|
|
|
|
|
#if BYTE_ORDER == LITTLE_ENDIAN |
29
|
|
|
|
|
|
|
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ |
30
|
|
|
|
|
|
|
|(rol(block->l[i],8)&0x00FF00FF)) |
31
|
|
|
|
|
|
|
#else |
32
|
|
|
|
|
|
|
#define blk0(i) block->l[i] |
33
|
|
|
|
|
|
|
#endif |
34
|
|
|
|
|
|
|
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ |
35
|
|
|
|
|
|
|
^block->l[(i+2)&15]^block->l[i&15],1)) |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ |
38
|
|
|
|
|
|
|
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); |
39
|
|
|
|
|
|
|
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); |
40
|
|
|
|
|
|
|
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); |
41
|
|
|
|
|
|
|
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); |
42
|
|
|
|
|
|
|
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
/* Hash a single 512-bit block. This is the core of the algorithm. */ |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
void |
47
|
20
|
|
|
|
|
|
ldns_sha1_transform(uint32_t state[5], const unsigned char buffer[LDNS_SHA1_BLOCK_LENGTH]) |
48
|
|
|
|
|
|
|
{ |
49
|
|
|
|
|
|
|
uint32_t a, b, c, d, e; |
50
|
|
|
|
|
|
|
typedef union { |
51
|
|
|
|
|
|
|
unsigned char c[64]; |
52
|
|
|
|
|
|
|
unsigned int l[16]; |
53
|
|
|
|
|
|
|
} CHAR64LONG16; |
54
|
|
|
|
|
|
|
CHAR64LONG16* block; |
55
|
|
|
|
|
|
|
#ifdef SHA1HANDSOFF |
56
|
|
|
|
|
|
|
unsigned char workspace[LDNS_SHA1_BLOCK_LENGTH]; |
57
|
|
|
|
|
|
|
|
58
|
20
|
|
|
|
|
|
block = (CHAR64LONG16 *)workspace; |
59
|
20
|
|
|
|
|
|
memmove(block, buffer, LDNS_SHA1_BLOCK_LENGTH); |
60
|
|
|
|
|
|
|
#else |
61
|
|
|
|
|
|
|
block = (CHAR64LONG16 *)buffer; |
62
|
|
|
|
|
|
|
#endif |
63
|
|
|
|
|
|
|
/* Copy context->state[] to working vars */ |
64
|
20
|
|
|
|
|
|
a = state[0]; |
65
|
20
|
|
|
|
|
|
b = state[1]; |
66
|
20
|
|
|
|
|
|
c = state[2]; |
67
|
20
|
|
|
|
|
|
d = state[3]; |
68
|
20
|
|
|
|
|
|
e = state[4]; |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
/* 4 rounds of 20 operations each. Loop unrolled. */ |
71
|
20
|
|
|
|
|
|
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); |
72
|
20
|
|
|
|
|
|
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); |
73
|
20
|
|
|
|
|
|
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); |
74
|
20
|
|
|
|
|
|
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); |
75
|
20
|
|
|
|
|
|
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); |
76
|
20
|
|
|
|
|
|
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); |
77
|
20
|
|
|
|
|
|
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); |
78
|
20
|
|
|
|
|
|
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); |
79
|
20
|
|
|
|
|
|
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); |
80
|
20
|
|
|
|
|
|
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); |
81
|
20
|
|
|
|
|
|
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); |
82
|
20
|
|
|
|
|
|
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); |
83
|
20
|
|
|
|
|
|
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); |
84
|
20
|
|
|
|
|
|
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); |
85
|
20
|
|
|
|
|
|
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); |
86
|
20
|
|
|
|
|
|
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); |
87
|
20
|
|
|
|
|
|
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); |
88
|
20
|
|
|
|
|
|
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); |
89
|
20
|
|
|
|
|
|
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); |
90
|
20
|
|
|
|
|
|
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); |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
/* Add the working vars back into context.state[] */ |
93
|
20
|
|
|
|
|
|
state[0] += a; |
94
|
20
|
|
|
|
|
|
state[1] += b; |
95
|
20
|
|
|
|
|
|
state[2] += c; |
96
|
20
|
|
|
|
|
|
state[3] += d; |
97
|
20
|
|
|
|
|
|
state[4] += e; |
98
|
|
|
|
|
|
|
/* Wipe variables */ |
99
|
20
|
|
|
|
|
|
a = b = c = d = e = 0; |
100
|
20
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
/* SHA1Init - Initialize new context */ |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
void |
106
|
4
|
|
|
|
|
|
ldns_sha1_init(ldns_sha1_ctx *context) |
107
|
|
|
|
|
|
|
{ |
108
|
|
|
|
|
|
|
/* SHA1 initialization constants */ |
109
|
4
|
|
|
|
|
|
context->count = 0; |
110
|
4
|
|
|
|
|
|
context->state[0] = 0x67452301; |
111
|
4
|
|
|
|
|
|
context->state[1] = 0xEFCDAB89; |
112
|
4
|
|
|
|
|
|
context->state[2] = 0x98BADCFE; |
113
|
4
|
|
|
|
|
|
context->state[3] = 0x10325476; |
114
|
4
|
|
|
|
|
|
context->state[4] = 0xC3D2E1F0; |
115
|
4
|
|
|
|
|
|
} |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
/* Run your data through this. */ |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
void |
121
|
168
|
|
|
|
|
|
ldns_sha1_update(ldns_sha1_ctx *context, const unsigned char *data, unsigned int len) |
122
|
|
|
|
|
|
|
{ |
123
|
|
|
|
|
|
|
unsigned int i; |
124
|
|
|
|
|
|
|
unsigned int j; |
125
|
|
|
|
|
|
|
|
126
|
168
|
|
|
|
|
|
j = (unsigned)(uint32_t)((context->count >> 3) & 63); |
127
|
168
|
|
|
|
|
|
context->count += (len << 3); |
128
|
168
|
100
|
|
|
|
|
if ((j + len) > 63) { |
129
|
7
|
|
|
|
|
|
memmove(&context->buffer[j], data, (i = 64 - j)); |
130
|
7
|
|
|
|
|
|
ldns_sha1_transform(context->state, context->buffer); |
131
|
16
|
100
|
|
|
|
|
for ( ; i + 63 < len; i += 64) { |
132
|
9
|
|
|
|
|
|
ldns_sha1_transform(context->state, &data[i]); |
133
|
|
|
|
|
|
|
} |
134
|
7
|
|
|
|
|
|
j = 0; |
135
|
|
|
|
|
|
|
} |
136
|
161
|
|
|
|
|
|
else i = 0; |
137
|
168
|
|
|
|
|
|
memmove(&context->buffer[j], &data[i], len - i); |
138
|
168
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
/* Add padding and return the message digest. */ |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
void |
144
|
4
|
|
|
|
|
|
ldns_sha1_final(unsigned char digest[LDNS_SHA1_DIGEST_LENGTH], ldns_sha1_ctx *context) |
145
|
|
|
|
|
|
|
{ |
146
|
|
|
|
|
|
|
unsigned int i; |
147
|
|
|
|
|
|
|
unsigned char finalcount[8]; |
148
|
|
|
|
|
|
|
|
149
|
36
|
100
|
|
|
|
|
for (i = 0; i < 8; i++) { |
150
|
64
|
|
|
|
|
|
finalcount[i] = (unsigned char)((context->count >> |
151
|
32
|
|
|
|
|
|
((7 - (i & 7)) * 8)) & 255); /* Endian independent */ |
152
|
|
|
|
|
|
|
} |
153
|
4
|
|
|
|
|
|
ldns_sha1_update(context, (unsigned char *)"\200", 1); |
154
|
160
|
100
|
|
|
|
|
while ((context->count & 504) != 448) { |
155
|
156
|
|
|
|
|
|
ldns_sha1_update(context, (unsigned char *)"\0", 1); |
156
|
|
|
|
|
|
|
} |
157
|
4
|
|
|
|
|
|
ldns_sha1_update(context, finalcount, 8); /* Should cause a SHA1Transform() */ |
158
|
|
|
|
|
|
|
|
159
|
4
|
50
|
|
|
|
|
if (digest != NULL) |
160
|
84
|
100
|
|
|
|
|
for (i = 0; i < LDNS_SHA1_DIGEST_LENGTH; i++) { |
161
|
160
|
|
|
|
|
|
digest[i] = (unsigned char)((context->state[i >> 2] >> |
162
|
80
|
|
|
|
|
|
((3 - (i & 3)) * 8)) & 255); |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */ |
165
|
4
|
|
|
|
|
|
ldns_sha1_transform(context->state, context->buffer); |
166
|
|
|
|
|
|
|
#endif |
167
|
4
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
unsigned char * |
170
|
4
|
|
|
|
|
|
ldns_sha1(unsigned char *data, unsigned int data_len, unsigned char *digest) |
171
|
|
|
|
|
|
|
{ |
172
|
|
|
|
|
|
|
ldns_sha1_ctx ctx; |
173
|
4
|
|
|
|
|
|
ldns_sha1_init(&ctx); |
174
|
4
|
|
|
|
|
|
ldns_sha1_update(&ctx, data, data_len); |
175
|
4
|
|
|
|
|
|
ldns_sha1_final(digest, &ctx); |
176
|
4
|
|
|
|
|
|
return digest; |
177
|
|
|
|
|
|
|
} |