File Coverage

_sha1.c
Criterion Covered Total %
statement 202 219 92.2
branch 10 20 50.0
condition n/a
subroutine n/a
pod n/a
total 212 239 88.7


line stmt bran cond sub pod time code
1             /* sha1.c - an implementation of Secure Hash Algorithm 1 (SHA1)
2             * based on RFC 3174.
3             *
4             * Copyright (c) 2008, Aleksey Kravchenko
5             *
6             * Permission to use, copy, modify, and/or distribute this software for any
7             * purpose with or without fee is hereby granted.
8             *
9             * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
10             * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11             * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
12             * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13             * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14             * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15             * PERFORMANCE OF THIS SOFTWARE.
16             */
17              
18             #include
19             #include "byte_order.h"
20             #include "sha1.h"
21              
22             /**
23             * Initialize context before calculating hash.
24             *
25             * @param ctx context to initialize
26             */
27 8           void rhash_sha1_init(sha1_ctx* ctx)
28             {
29 8           ctx->length = 0;
30              
31             /* initialize algorithm state */
32 8           ctx->hash[0] = 0x67452301;
33 8           ctx->hash[1] = 0xefcdab89;
34 8           ctx->hash[2] = 0x98badcfe;
35 8           ctx->hash[3] = 0x10325476;
36 8           ctx->hash[4] = 0xc3d2e1f0;
37 8           }
38              
39             /* constants for SHA1 rounds */
40             static const uint32_t K0 = 0x5a827999;
41             static const uint32_t K1 = 0x6ed9eba1;
42             static const uint32_t K2 = 0x8f1bbcdc;
43             static const uint32_t K3 = 0xca62c1d6;
44              
45             /* round functions for SHA1 */
46             #define CHO(X,Y,Z) (((X)&(Y))|((~(X))&(Z)))
47             #define PAR(X,Y,Z) ((X)^(Y)^(Z))
48             #define MAJ(X,Y,Z) (((X)&(Y))|((X)&(Z))|((Y)&(Z)))
49              
50             #define ROUND_0(a,b,c,d,e, FF, k, w) e += FF(b, c, d )+ROTL32(a,5)+k+w
51             #define ROUND_1(a,b,c,d,e, FF, k, w) e += FF(b,ROTL32(c,30), d )+ROTL32(a,5)+k+w
52             #define ROUND_2(a,b,c,d,e, FF, k, w) e += FF(b,ROTL32(c,30),ROTL32(d,30))+ROTL32(a,5)+k+w
53             #define ROUND(a,b,c,d,e, FF, k, w) e = ROTL32(e,30)+FF(b,ROTL32(c,30),ROTL32(d,30))+ROTL32(a,5)+k+w
54              
55              
56             /**
57             * The core transformation. Process a 512-bit block.
58             * The function has been taken from RFC 3174 with little changes.
59             *
60             * @param hash algorithm state
61             * @param block the message block to process
62             */
63 8           static void rhash_sha1_process_block(unsigned* hash, const unsigned* block)
64             {
65             uint32_t W[80]; /* Word sequence */
66             uint32_t A, B, C, D, E; /* Word buffers */
67              
68              
69 8           A = hash[0];
70 8           B = hash[1];
71 8           C = hash[2];
72 8           D = hash[3];
73 8           E = hash[4];
74              
75             /* 0..19 */
76 8           W[ 0] = be2me_32(block[ 0]);
77 8           ROUND_0(A,B,C,D,E, CHO, K0, W[ 0]);
78 8           W[ 1] = be2me_32(block[ 1]);
79 8           ROUND_1(E,A,B,C,D, CHO, K0, W[ 1]);
80 8           W[ 2] = be2me_32(block[ 2]);
81 8           ROUND_2(D,E,A,B,C, CHO, K0, W[ 2]);
82 8           W[ 3] = be2me_32(block[ 3]);
83 8           ROUND(C,D,E,A,B, CHO, K0, W[ 3]);
84 8           W[ 4] = be2me_32(block[ 4]);
85 8           ROUND(B,C,D,E,A, CHO, K0, W[ 4]);
86              
87 8           W[ 5] = be2me_32(block[ 5]);
88 8           ROUND(A,B,C,D,E, CHO, K0, W[ 5]);
89 8           W[ 6] = be2me_32(block[ 6]);
90 8           ROUND(E,A,B,C,D, CHO, K0, W[ 6]);
91 8           W[ 7] = be2me_32(block[ 7]);
92 8           ROUND(D,E,A,B,C, CHO, K0, W[ 7]);
93 8           W[ 8] = be2me_32(block[ 8]);
94 8           ROUND(C,D,E,A,B, CHO, K0, W[ 8]);
95 8           W[ 9] = be2me_32(block[ 9]);
96 8           ROUND(B,C,D,E,A, CHO, K0, W[ 9]);
97              
98 8           W[10] = be2me_32(block[10]);
99 8           ROUND(A,B,C,D,E, CHO, K0, W[10]);
100 8           W[11] = be2me_32(block[11]);
101 8           ROUND(E,A,B,C,D, CHO, K0, W[11]);
102 8           W[12] = be2me_32(block[12]);
103 8           ROUND(D,E,A,B,C, CHO, K0, W[12]);
104 8           W[13] = be2me_32(block[13]);
105 8           ROUND(C,D,E,A,B, CHO, K0, W[13]);
106 8           W[14] = be2me_32(block[14]);
107 8           ROUND(B,C,D,E,A, CHO, K0, W[14]);
108              
109 8           W[15] = be2me_32(block[15]);
110 8           ROUND(A,B,C,D,E, CHO, K0, W[15]);
111 8           W[16] = ROTL32(W[13] ^ W[ 8] ^ W[ 2] ^ W[ 0], 1);
112 8           ROUND(E,A,B,C,D, CHO, K0, W[16]);
113 8           W[17] = ROTL32(W[14] ^ W[ 9] ^ W[ 3] ^ W[ 1], 1);
114 8           ROUND(D,E,A,B,C, CHO, K0, W[17]);
115 8           W[18] = ROTL32(W[15] ^ W[10] ^ W[ 4] ^ W[ 2], 1);
116 8           ROUND(C,D,E,A,B, CHO, K0, W[18]);
117 8           W[19] = ROTL32(W[16] ^ W[11] ^ W[ 5] ^ W[ 3], 1);
118 8           ROUND(B,C,D,E,A, CHO, K0, W[19]);
119             /* 20..39 */
120 8           W[20] = ROTL32(W[17] ^ W[12] ^ W[ 6] ^ W[ 4], 1);
121 8           ROUND(A,B,C,D,E, PAR, K1, W[20]);
122 8           W[21] = ROTL32(W[18] ^ W[13] ^ W[ 7] ^ W[ 5], 1);
123 8           ROUND(E,A,B,C,D, PAR, K1, W[21]);
124 8           W[22] = ROTL32(W[19] ^ W[14] ^ W[ 8] ^ W[ 6], 1);
125 8           ROUND(D,E,A,B,C, PAR, K1, W[22]);
126 8           W[23] = ROTL32(W[20] ^ W[15] ^ W[ 9] ^ W[ 7], 1);
127 8           ROUND(C,D,E,A,B, PAR, K1, W[23]);
128 8           W[24] = ROTL32(W[21] ^ W[16] ^ W[10] ^ W[ 8], 1);
129 8           ROUND(B,C,D,E,A, PAR, K1, W[24]);
130              
131 8           W[25] = ROTL32(W[22] ^ W[17] ^ W[11] ^ W[ 9], 1);
132 8           ROUND(A,B,C,D,E, PAR, K1, W[25]);
133 8           W[26] = ROTL32(W[23] ^ W[18] ^ W[12] ^ W[10], 1);
134 8           ROUND(E,A,B,C,D, PAR, K1, W[26]);
135 8           W[27] = ROTL32(W[24] ^ W[19] ^ W[13] ^ W[11], 1);
136 8           ROUND(D,E,A,B,C, PAR, K1, W[27]);
137 8           W[28] = ROTL32(W[25] ^ W[20] ^ W[14] ^ W[12], 1);
138 8           ROUND(C,D,E,A,B, PAR, K1, W[28]);
139 8           W[29] = ROTL32(W[26] ^ W[21] ^ W[15] ^ W[13], 1);
140 8           ROUND(B,C,D,E,A, PAR, K1, W[29]);
141              
142 8           W[30] = ROTL32(W[27] ^ W[22] ^ W[16] ^ W[14], 1);
143 8           ROUND(A,B,C,D,E, PAR, K1, W[30]);
144 8           W[31] = ROTL32(W[28] ^ W[23] ^ W[17] ^ W[15], 1);
145 8           ROUND(E,A,B,C,D, PAR, K1, W[31]);
146 8           W[32] = ROTL32(W[29] ^ W[24] ^ W[18] ^ W[16], 1);
147 8           ROUND(D,E,A,B,C, PAR, K1, W[32]);
148 8           W[33] = ROTL32(W[30] ^ W[25] ^ W[19] ^ W[17], 1);
149 8           ROUND(C,D,E,A,B, PAR, K1, W[33]);
150 8           W[34] = ROTL32(W[31] ^ W[26] ^ W[20] ^ W[18], 1);
151 8           ROUND(B,C,D,E,A, PAR, K1, W[34]);
152              
153 8           W[35] = ROTL32(W[32] ^ W[27] ^ W[21] ^ W[19], 1);
154 8           ROUND(A,B,C,D,E, PAR, K1, W[35]);
155 8           W[36] = ROTL32(W[33] ^ W[28] ^ W[22] ^ W[20], 1);
156 8           ROUND(E,A,B,C,D, PAR, K1, W[36]);
157 8           W[37] = ROTL32(W[34] ^ W[29] ^ W[23] ^ W[21], 1);
158 8           ROUND(D,E,A,B,C, PAR, K1, W[37]);
159 8           W[38] = ROTL32(W[35] ^ W[30] ^ W[24] ^ W[22], 1);
160 8           ROUND(C,D,E,A,B, PAR, K1, W[38]);
161 8           W[39] = ROTL32(W[36] ^ W[31] ^ W[25] ^ W[23], 1);
162 8           ROUND(B,C,D,E,A, PAR, K1, W[39]);
163             /* 40..59 */
164 8           W[40] = ROTL32(W[37] ^ W[32] ^ W[26] ^ W[24], 1);
165 8           ROUND(A,B,C,D,E, MAJ, K2, W[40]);
166 8           W[41] = ROTL32(W[38] ^ W[33] ^ W[27] ^ W[25], 1);
167 8           ROUND(E,A,B,C,D, MAJ, K2, W[41]);
168 8           W[42] = ROTL32(W[39] ^ W[34] ^ W[28] ^ W[26], 1);
169 8           ROUND(D,E,A,B,C, MAJ, K2, W[42]);
170 8           W[43] = ROTL32(W[40] ^ W[35] ^ W[29] ^ W[27], 1);
171 8           ROUND(C,D,E,A,B, MAJ, K2, W[43]);
172 8           W[44] = ROTL32(W[41] ^ W[36] ^ W[30] ^ W[28], 1);
173 8           ROUND(B,C,D,E,A, MAJ, K2, W[44]);
174              
175 8           W[45] = ROTL32(W[42] ^ W[37] ^ W[31] ^ W[29], 1);
176 8           ROUND(A,B,C,D,E, MAJ, K2, W[45]);
177 8           W[46] = ROTL32(W[43] ^ W[38] ^ W[32] ^ W[30], 1);
178 8           ROUND(E,A,B,C,D, MAJ, K2, W[46]);
179 8           W[47] = ROTL32(W[44] ^ W[39] ^ W[33] ^ W[31], 1);
180 8           ROUND(D,E,A,B,C, MAJ, K2, W[47]);
181 8           W[48] = ROTL32(W[45] ^ W[40] ^ W[34] ^ W[32], 1);
182 8           ROUND(C,D,E,A,B, MAJ, K2, W[48]);
183 8           W[49] = ROTL32(W[46] ^ W[41] ^ W[35] ^ W[33], 1);
184 8           ROUND(B,C,D,E,A, MAJ, K2, W[49]);
185              
186 8           W[50] = ROTL32(W[47] ^ W[42] ^ W[36] ^ W[34], 1);
187 8           ROUND(A,B,C,D,E, MAJ, K2, W[50]);
188 8           W[51] = ROTL32(W[48] ^ W[43] ^ W[37] ^ W[35], 1);
189 8           ROUND(E,A,B,C,D, MAJ, K2, W[51]);
190 8           W[52] = ROTL32(W[49] ^ W[44] ^ W[38] ^ W[36], 1);
191 8           ROUND(D,E,A,B,C, MAJ, K2, W[52]);
192 8           W[53] = ROTL32(W[50] ^ W[45] ^ W[39] ^ W[37], 1);
193 8           ROUND(C,D,E,A,B, MAJ, K2, W[53]);
194 8           W[54] = ROTL32(W[51] ^ W[46] ^ W[40] ^ W[38], 1);
195 8           ROUND(B,C,D,E,A, MAJ, K2, W[54]);
196              
197 8           W[55] = ROTL32(W[52] ^ W[47] ^ W[41] ^ W[39], 1);
198 8           ROUND(A,B,C,D,E, MAJ, K2, W[55]);
199 8           W[56] = ROTL32(W[53] ^ W[48] ^ W[42] ^ W[40], 1);
200 8           ROUND(E,A,B,C,D, MAJ, K2, W[56]);
201 8           W[57] = ROTL32(W[54] ^ W[49] ^ W[43] ^ W[41], 1);
202 8           ROUND(D,E,A,B,C, MAJ, K2, W[57]);
203 8           W[58] = ROTL32(W[55] ^ W[50] ^ W[44] ^ W[42], 1);
204 8           ROUND(C,D,E,A,B, MAJ, K2, W[58]);
205 8           W[59] = ROTL32(W[56] ^ W[51] ^ W[45] ^ W[43], 1);
206 8           ROUND(B,C,D,E,A, MAJ, K2, W[59]);
207             /* 60..79 */
208 8           W[60] = ROTL32(W[57] ^ W[52] ^ W[46] ^ W[44], 1);
209 8           ROUND(A,B,C,D,E, PAR, K3, W[60]);
210 8           W[61] = ROTL32(W[58] ^ W[53] ^ W[47] ^ W[45], 1);
211 8           ROUND(E,A,B,C,D, PAR, K3, W[61]);
212 8           W[62] = ROTL32(W[59] ^ W[54] ^ W[48] ^ W[46], 1);
213 8           ROUND(D,E,A,B,C, PAR, K3, W[62]);
214 8           W[63] = ROTL32(W[60] ^ W[55] ^ W[49] ^ W[47], 1);
215 8           ROUND(C,D,E,A,B, PAR, K3, W[63]);
216 8           W[64] = ROTL32(W[61] ^ W[56] ^ W[50] ^ W[48], 1);
217 8           ROUND(B,C,D,E,A, PAR, K3, W[64]);
218              
219 8           W[65] = ROTL32(W[62] ^ W[57] ^ W[51] ^ W[49], 1);
220 8           ROUND(A,B,C,D,E, PAR, K3, W[65]);
221 8           W[66] = ROTL32(W[63] ^ W[58] ^ W[52] ^ W[50], 1);
222 8           ROUND(E,A,B,C,D, PAR, K3, W[66]);
223 8           W[67] = ROTL32(W[64] ^ W[59] ^ W[53] ^ W[51], 1);
224 8           ROUND(D,E,A,B,C, PAR, K3, W[67]);
225 8           W[68] = ROTL32(W[65] ^ W[60] ^ W[54] ^ W[52], 1);
226 8           ROUND(C,D,E,A,B, PAR, K3, W[68]);
227 8           W[69] = ROTL32(W[66] ^ W[61] ^ W[55] ^ W[53], 1);
228 8           ROUND(B,C,D,E,A, PAR, K3, W[69]);
229              
230 8           W[70] = ROTL32(W[67] ^ W[62] ^ W[56] ^ W[54], 1);
231 8           ROUND(A,B,C,D,E, PAR, K3, W[70]);
232 8           W[71] = ROTL32(W[68] ^ W[63] ^ W[57] ^ W[55], 1);
233 8           ROUND(E,A,B,C,D, PAR, K3, W[71]);
234 8           W[72] = ROTL32(W[69] ^ W[64] ^ W[58] ^ W[56], 1);
235 8           ROUND(D,E,A,B,C, PAR, K3, W[72]);
236 8           W[73] = ROTL32(W[70] ^ W[65] ^ W[59] ^ W[57], 1);
237 8           ROUND(C,D,E,A,B, PAR, K3, W[73]);
238 8           W[74] = ROTL32(W[71] ^ W[66] ^ W[60] ^ W[58], 1);
239 8           ROUND(B,C,D,E,A, PAR, K3, W[74]);
240              
241 8           W[75] = ROTL32(W[72] ^ W[67] ^ W[61] ^ W[59], 1);
242 8           ROUND(A,B,C,D,E, PAR, K3, W[75]);
243 8           W[76] = ROTL32(W[73] ^ W[68] ^ W[62] ^ W[60], 1);
244 8           ROUND(E,A,B,C,D, PAR, K3, W[76]);
245 8           W[77] = ROTL32(W[74] ^ W[69] ^ W[63] ^ W[61], 1);
246 8           ROUND(D,E,A,B,C, PAR, K3, W[77]);
247 8           W[78] = ROTL32(W[75] ^ W[70] ^ W[64] ^ W[62], 1);
248 8           ROUND(C,D,E,A,B, PAR, K3, W[78]);
249 8           W[79] = ROTL32(W[76] ^ W[71] ^ W[65] ^ W[63], 1);
250 8           ROUND(B,C,D,E,A, PAR, K3, W[79]);
251              
252              
253 8           hash[0] += A;
254 8           hash[1] += B;
255 8           hash[2] += ROTL32(C,30);
256 8           hash[3] += ROTL32(D,30);
257 8           hash[4] += ROTL32(E,30);
258 8           }
259              
260             /**
261             * Calculate message hash.
262             * Can be called repeatedly with chunks of the message to be hashed.
263             *
264             * @param ctx the algorithm context containing current hashing state
265             * @param msg message chunk
266             * @param size length of the message chunk
267             */
268 8           void rhash_sha1_update(sha1_ctx* ctx, const unsigned char* msg, size_t size)
269             {
270 8           unsigned index = (unsigned)ctx->length & 63;
271 8           ctx->length += size;
272              
273             /* fill partial block */
274 8 50         if (index) {
275 0           unsigned left = sha1_block_size - index;
276 0           memcpy(ctx->message + index, msg, (size < left ? size : left));
277 0 0         if (size < left) return;
278              
279             /* process partial block */
280 0           rhash_sha1_process_block(ctx->hash, (unsigned*)ctx->message);
281 0           msg += left;
282 0           size -= left;
283             }
284 8 50         while (size >= sha1_block_size) {
285             unsigned* aligned_message_block;
286 0 0         if (IS_ALIGNED_32(msg)) {
287             /* the most common case is processing of an already aligned message
288             without copying it */
289 0           aligned_message_block = (unsigned*)msg;
290             } else {
291 0           memcpy(ctx->message, msg, sha1_block_size);
292 0           aligned_message_block = (unsigned*)ctx->message;
293             }
294              
295 0           rhash_sha1_process_block(ctx->hash, aligned_message_block);
296 0           msg += sha1_block_size;
297 0           size -= sha1_block_size;
298             }
299 8 50         if (size) {
300             /* save leftovers */
301 8           memcpy(ctx->message, msg, size);
302             }
303             }
304              
305             /**
306             * Store calculated hash into the given array.
307             *
308             * @param ctx the algorithm context containing current hashing state
309             * @param result calculated hash in binary form
310             */
311 8           void rhash_sha1_final(sha1_ctx* ctx, unsigned char* result)
312             {
313 8           unsigned index = (unsigned)ctx->length & 63;
314 8           unsigned* msg32 = (unsigned*)ctx->message;
315              
316             /* pad message and run for last block */
317 8           ctx->message[index++] = 0x80;
318 20 100         while ((index & 3) != 0) {
319 12           ctx->message[index++] = 0;
320             }
321 8           index >>= 2;
322              
323             /* if no room left in the message to store 64-bit message length */
324 8 50         if (index > 14) {
325             /* then fill the rest with zeros and process it */
326 0 0         while (index < 16) {
327 0           msg32[index++] = 0;
328             }
329 0           rhash_sha1_process_block(ctx->hash, msg32);
330 0           index = 0;
331             }
332 86 100         while (index < 14) {
333 78           msg32[index++] = 0;
334             }
335 8           msg32[14] = be2me_32( (unsigned)(ctx->length >> 29) );
336 8           msg32[15] = be2me_32( (unsigned)(ctx->length << 3) );
337 8           rhash_sha1_process_block(ctx->hash, msg32);
338              
339 8 100         if (result) be32_copy(result, 0, &ctx->hash, sha1_hash_size);
340 8           }