Line | Branch | Exec | Source |
---|---|---|---|
1 | /* GATE PROJECT LICENSE: | ||
2 | +----------------------------------------------------------------------------+ | ||
3 | | Copyright(c) 2018-2025, Stefan Meislinger <sm@opengate.at> | | ||
4 | | All rights reserved. | | ||
5 | | | | ||
6 | | Redistribution and use in source and binary forms, with or without | | ||
7 | | modification, are permitted provided that the following conditions are met:| | ||
8 | | | | ||
9 | | 1. Redistributions of source code must retain the above copyright notice, | | ||
10 | | this list of conditions and the following disclaimer. | | ||
11 | | 2. Redistributions in binary form must reproduce the above copyright | | ||
12 | | notice, this list of conditions and the following disclaimer in the | | ||
13 | | documentation and/or other materials provided with the distribution. | | ||
14 | | | | ||
15 | | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"| | ||
16 | | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | ||
17 | | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | ||
18 | | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | | ||
19 | | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | ||
20 | | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | ||
21 | | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | ||
22 | | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | ||
23 | | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | ||
24 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | ||
25 | | THE POSSIBILITY OF SUCH DAMAGE. | | ||
26 | +----------------------------------------------------------------------------+ | ||
27 | */ | ||
28 | |||
29 | #include "gate/encode/sha1hash.h" | ||
30 | #include "gate/memalloc.h" | ||
31 | |||
32 | /* Public information: http://en.wikipedia.org/wiki/SHA-1 */ | ||
33 | |||
34 | 208 | static unsigned long uint32_load(unsigned char const* buffer) | |
35 | { | ||
36 | 208 | return (((unsigned long)buffer[0] & 0xff) << 24) | |
37 | 208 | | (((unsigned long)buffer[1] & 0xff) << 16) | |
38 | 208 | | (((unsigned long)buffer[2] & 0xff) << 8) | |
39 | 208 | | (((unsigned long)buffer[3] & 0xff)) | |
40 | ; | ||
41 | } | ||
42 | |||
43 | 49 | static void uint32_save(unsigned long value, unsigned char* buffer) | |
44 | { | ||
45 | 49 | buffer[0] = (unsigned char)((value >> 24) & 0xff); | |
46 | 49 | buffer[1] = (unsigned char)((value >> 16) & 0xff); | |
47 | 49 | buffer[2] = (unsigned char)((value >> 8) & 0xff); | |
48 | 49 | buffer[3] = (unsigned char)((value) & 0xff); | |
49 | 49 | } | |
50 | |||
51 | 2912 | static unsigned long left_rot(unsigned long value, unsigned n) | |
52 | { | ||
53 | 2912 | return ((value << n) & 0xffffffff) | ((value >> (32 - n)) & 0xffffffff); | |
54 | } | ||
55 | |||
56 | 13 | static void gate_sha1_add(gate_sha1_t* context, unsigned char const* block) | |
57 | { | ||
58 | unsigned n; | ||
59 | |||
60 | 13 | unsigned long a = context->a; | |
61 | 13 | unsigned long b = context->b; | |
62 | 13 | unsigned long c = context->c; | |
63 | 13 | unsigned long d = context->d; | |
64 | 13 | unsigned long e = context->e; | |
65 | unsigned long f, k, t; | ||
66 | unsigned long w[80]; | ||
67 | |||
68 |
2/2✓ Branch 0 taken 208 times.
✓ Branch 1 taken 13 times.
|
221 | for (n = 0; n != 16; ++n) |
69 | { | ||
70 | 208 | w[n] = uint32_load(&block[n * 4]); | |
71 | } | ||
72 | |||
73 |
2/2✓ Branch 0 taken 832 times.
✓ Branch 1 taken 13 times.
|
845 | for (n = 16; n < 80; ++n) |
74 | { | ||
75 | 832 | w[n] = left_rot(w[n - 3] ^ w[n - 8] ^ w[n - 14] ^ w[n - 16], 1); | |
76 | } | ||
77 | |||
78 |
2/2✓ Branch 0 taken 1040 times.
✓ Branch 1 taken 13 times.
|
1053 | for (n = 0; n < 80; ++n) |
79 | { | ||
80 |
2/2✓ Branch 0 taken 260 times.
✓ Branch 1 taken 780 times.
|
1040 | if (n < 20) |
81 | { | ||
82 | 260 | f = (b & c) | ((~b) & d); | |
83 | 260 | k = 0x5A827999; | |
84 | } | ||
85 |
2/2✓ Branch 0 taken 260 times.
✓ Branch 1 taken 520 times.
|
780 | else if (n < 40) |
86 | { | ||
87 | 260 | f = b ^ c ^ d; | |
88 | 260 | k = 0x6ED9EBA1; | |
89 | } | ||
90 |
2/2✓ Branch 0 taken 260 times.
✓ Branch 1 taken 260 times.
|
520 | else if (n < 60) |
91 | { | ||
92 | 260 | f = (b & c) | (b & d) | (c & d); | |
93 | 260 | k = 0x8F1BBCDC; | |
94 | } | ||
95 | else | ||
96 | { | ||
97 | 260 | f = (b ^ c ^ d); | |
98 | 260 | k = 0xCA62C1D6; | |
99 | } | ||
100 | 1040 | t = (left_rot(a, 5) + f + e + k + w[n]) & 0xffffffff; | |
101 | 1040 | e = d; | |
102 | 1040 | d = c; | |
103 | 1040 | c = left_rot(b, 30); | |
104 | 1040 | b = a; | |
105 | 1040 | a = t; | |
106 | } | ||
107 | |||
108 | 13 | context->a = (context->a + a) & 0xffffffff; | |
109 | 13 | context->b = (context->b + b) & 0xffffffff; | |
110 | 13 | context->c = (context->c + c) & 0xffffffff; | |
111 | 13 | context->d = (context->d + d) & 0xffffffff; | |
112 | 13 | context->e = (context->e + e) & 0xffffffff; | |
113 | 13 | } | |
114 | |||
115 | 8 | void gate_sha1_init(gate_sha1_t* context) | |
116 | { | ||
117 | 8 | context->a = 0x67452301; | |
118 | 8 | context->b = 0xEFCDAB89; | |
119 | 8 | context->c = 0x98BADCFE; | |
120 | 8 | context->d = 0x10325476; | |
121 | 8 | context->e = 0xC3D2E1F0; | |
122 | |||
123 | 8 | context->bufferused = 0; | |
124 | 8 | context->msglength = 0; | |
125 | 8 | } | |
126 | 7 | void gate_sha1_update(gate_sha1_t* context, void const* buffer, gate_size_t length) | |
127 | { | ||
128 | 7 | unsigned char const* ptr = (unsigned char const*)buffer; | |
129 | |||
130 | 7 | context->msglength += length; | |
131 | |||
132 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
|
7 | if (context->bufferused > 0) |
133 | { | ||
134 | 1 | gate_size_t freebytes = GATE_SHA1_BLOCK_LENGTH - context->bufferused; | |
135 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (length < freebytes) |
136 | { | ||
137 | ✗ | gate_mem_copy(&context->buffer[context->bufferused], ptr, length); | |
138 | ✗ | context->bufferused += length; | |
139 | ✗ | return; | |
140 | } | ||
141 | else | ||
142 | { | ||
143 | 1 | gate_mem_copy(&context->buffer[context->bufferused], ptr, freebytes); | |
144 | 1 | gate_sha1_add(context, &context->buffer[0]); | |
145 | 1 | context->bufferused = 0; | |
146 | 1 | ptr += freebytes; | |
147 | 1 | length -= freebytes; | |
148 | } | ||
149 | } | ||
150 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 7 times.
|
12 | while (length >= GATE_SHA1_BLOCK_LENGTH) |
151 | { | ||
152 | 5 | gate_sha1_add(context, ptr); | |
153 | 5 | ptr += GATE_SHA1_BLOCK_LENGTH; | |
154 | 5 | length -= GATE_SHA1_BLOCK_LENGTH; | |
155 | } | ||
156 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (length > 0) |
157 | { | ||
158 | 7 | gate_mem_copy(context->buffer, ptr, length); | |
159 | 7 | context->bufferused = length; | |
160 | } | ||
161 | } | ||
162 | |||
163 | 7 | void gate_sha1_finish(gate_sha1_t* context, gate_sha1_result_t* result) | |
164 | { | ||
165 | 7 | gate_uint64_t bitlen = context->msglength * 8; | |
166 | 7 | unsigned long bitlen_high = (unsigned long)(bitlen >> 32); | |
167 | 7 | unsigned long bitlen_low = (unsigned long)(bitlen & 0xffffffff); | |
168 | 7 | gate_size_t freebytes = (GATE_SHA1_BLOCK_LENGTH - context->bufferused - 1); | |
169 | 7 | context->buffer[context->bufferused++] = 0x80; | |
170 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (freebytes < 8) |
171 | { | ||
172 | ✗ | gate_mem_clear(&context->buffer[context->bufferused], freebytes); | |
173 | ✗ | gate_sha1_add(context, &context->buffer[0]); | |
174 | ✗ | freebytes = GATE_SHA1_BLOCK_LENGTH; | |
175 | ✗ | context->bufferused = 0; | |
176 | } | ||
177 | 7 | gate_mem_clear(&context->buffer[context->bufferused], GATE_SHA1_BLOCK_LENGTH - 8 - context->bufferused); | |
178 | 7 | uint32_save(bitlen_high, &context->buffer[56]); | |
179 | 7 | uint32_save(bitlen_low, &context->buffer[60]); | |
180 | |||
181 | 7 | gate_sha1_add(context, context->buffer); | |
182 | |||
183 | 7 | uint32_save(context->a, &result->hash[0]); | |
184 | 7 | uint32_save(context->b, &result->hash[4]); | |
185 | 7 | uint32_save(context->c, &result->hash[8]); | |
186 | 7 | uint32_save(context->d, &result->hash[12]); | |
187 | 7 | uint32_save(context->e, &result->hash[16]); | |
188 | 7 | } | |
189 | |||
190 |