diff options
Diffstat (limited to 'openbsd-compat/sha1.c')
-rw-r--r-- | openbsd-compat/sha1.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/openbsd-compat/sha1.c b/openbsd-compat/sha1.c new file mode 100644 index 000000000..4b5381f87 --- /dev/null +++ b/openbsd-compat/sha1.c | |||
@@ -0,0 +1,177 @@ | |||
1 | /* $OpenBSD: sha1.c,v 1.23 2014/01/08 06:14:57 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 | #include "includes.h" | ||
18 | |||
19 | #ifndef WITH_OPENSSL | ||
20 | |||
21 | #include <sys/param.h> | ||
22 | #include <string.h> | ||
23 | |||
24 | #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) | ||
25 | |||
26 | /* | ||
27 | * blk0() and blk() perform the initial expand. | ||
28 | * I got the idea of expanding during the round function from SSLeay | ||
29 | */ | ||
30 | #if BYTE_ORDER == LITTLE_ENDIAN | ||
31 | # define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ | ||
32 | |(rol(block->l[i],8)&0x00FF00FF)) | ||
33 | #else | ||
34 | # define blk0(i) block->l[i] | ||
35 | #endif | ||
36 | #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ | ||
37 | ^block->l[(i+2)&15]^block->l[i&15],1)) | ||
38 | |||
39 | /* | ||
40 | * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 | ||
41 | */ | ||
42 | #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); | ||
43 | #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); | ||
44 | #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); | ||
45 | #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); | ||
46 | #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); | ||
47 | |||
48 | typedef union { | ||
49 | u_int8_t c[64]; | ||
50 | u_int32_t l[16]; | ||
51 | } CHAR64LONG16; | ||
52 | |||
53 | /* | ||
54 | * Hash a single 512-bit block. This is the core of the algorithm. | ||
55 | */ | ||
56 | void | ||
57 | SHA1Transform(u_int32_t state[5], const u_int8_t buffer[SHA1_BLOCK_LENGTH]) | ||
58 | { | ||
59 | u_int32_t a, b, c, d, e; | ||
60 | u_int8_t workspace[SHA1_BLOCK_LENGTH]; | ||
61 | CHAR64LONG16 *block = (CHAR64LONG16 *)workspace; | ||
62 | |||
63 | (void)memcpy(block, buffer, SHA1_BLOCK_LENGTH); | ||
64 | |||
65 | /* Copy context->state[] to working vars */ | ||
66 | a = state[0]; | ||
67 | b = state[1]; | ||
68 | c = state[2]; | ||
69 | d = state[3]; | ||
70 | e = state[4]; | ||
71 | |||
72 | /* 4 rounds of 20 operations each. Loop unrolled. */ | ||
73 | 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); | ||
74 | 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); | ||
75 | 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); | ||
76 | 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); | ||
77 | 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); | ||
78 | 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); | ||
79 | 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); | ||
80 | 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); | ||
81 | 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); | ||
82 | 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); | ||
83 | 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); | ||
84 | 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); | ||
85 | 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); | ||
86 | 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); | ||
87 | 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); | ||
88 | 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); | ||
89 | 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); | ||
90 | 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); | ||
91 | 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); | ||
92 | 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); | ||
93 | |||
94 | /* Add the working vars back into context.state[] */ | ||
95 | state[0] += a; | ||
96 | state[1] += b; | ||
97 | state[2] += c; | ||
98 | state[3] += d; | ||
99 | state[4] += e; | ||
100 | |||
101 | /* Wipe variables */ | ||
102 | a = b = c = d = e = 0; | ||
103 | } | ||
104 | |||
105 | |||
106 | /* | ||
107 | * SHA1Init - Initialize new context | ||
108 | */ | ||
109 | void | ||
110 | SHA1Init(SHA1_CTX *context) | ||
111 | { | ||
112 | |||
113 | /* SHA1 initialization constants */ | ||
114 | context->count = 0; | ||
115 | context->state[0] = 0x67452301; | ||
116 | context->state[1] = 0xEFCDAB89; | ||
117 | context->state[2] = 0x98BADCFE; | ||
118 | context->state[3] = 0x10325476; | ||
119 | context->state[4] = 0xC3D2E1F0; | ||
120 | } | ||
121 | |||
122 | |||
123 | /* | ||
124 | * Run your data through this. | ||
125 | */ | ||
126 | void | ||
127 | SHA1Update(SHA1_CTX *context, const u_int8_t *data, size_t len) | ||
128 | { | ||
129 | size_t i, j; | ||
130 | |||
131 | j = (size_t)((context->count >> 3) & 63); | ||
132 | context->count += (len << 3); | ||
133 | if ((j + len) > 63) { | ||
134 | (void)memcpy(&context->buffer[j], data, (i = 64-j)); | ||
135 | SHA1Transform(context->state, context->buffer); | ||
136 | for ( ; i + 63 < len; i += 64) | ||
137 | SHA1Transform(context->state, (u_int8_t *)&data[i]); | ||
138 | j = 0; | ||
139 | } else { | ||
140 | i = 0; | ||
141 | } | ||
142 | (void)memcpy(&context->buffer[j], &data[i], len - i); | ||
143 | } | ||
144 | |||
145 | |||
146 | /* | ||
147 | * Add padding and return the message digest. | ||
148 | */ | ||
149 | void | ||
150 | SHA1Pad(SHA1_CTX *context) | ||
151 | { | ||
152 | u_int8_t finalcount[8]; | ||
153 | u_int i; | ||
154 | |||
155 | for (i = 0; i < 8; i++) { | ||
156 | finalcount[i] = (u_int8_t)((context->count >> | ||
157 | ((7 - (i & 7)) * 8)) & 255); /* Endian independent */ | ||
158 | } | ||
159 | SHA1Update(context, (u_int8_t *)"\200", 1); | ||
160 | while ((context->count & 504) != 448) | ||
161 | SHA1Update(context, (u_int8_t *)"\0", 1); | ||
162 | SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ | ||
163 | } | ||
164 | |||
165 | void | ||
166 | SHA1Final(u_int8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context) | ||
167 | { | ||
168 | u_int i; | ||
169 | |||
170 | SHA1Pad(context); | ||
171 | for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { | ||
172 | digest[i] = (u_int8_t) | ||
173 | ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); | ||
174 | } | ||
175 | memset(context, 0, sizeof(*context)); | ||
176 | } | ||
177 | #endif /* !WITH_OPENSSL */ | ||