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/sha256hash.h" | ||
30 | #include "gate/memalloc.h" | ||
31 | |||
32 | /* Public information: http://en.wikipedia.org/wiki/SHA-2 */ | ||
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 | 70 | static void uint32_save(unsigned long value, unsigned char* buffer) | |
44 | { | ||
45 | 70 | buffer[0] = (unsigned char)((value >> 24) & 0xff); | |
46 | 70 | buffer[1] = (unsigned char)((value >> 16) & 0xff); | |
47 | 70 | buffer[2] = (unsigned char)((value >> 8) & 0xff); | |
48 | 70 | buffer[3] = (unsigned char)((value) & 0xff); | |
49 | 70 | } | |
50 | |||
51 | 7488 | static unsigned long rotate_right32(unsigned long value, unsigned n) | |
52 | { | ||
53 | 7488 | return ((value >> n) & 0xffffffff) | ((value << (32 - n)) & 0xffffffff); | |
54 | } | ||
55 | |||
56 | static unsigned long const k[64] = { | ||
57 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, | ||
58 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, | ||
59 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, | ||
60 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, | ||
61 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, | ||
62 | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, | ||
63 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, | ||
64 | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, | ||
65 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, | ||
66 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, | ||
67 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, | ||
68 | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, | ||
69 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, | ||
70 | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, | ||
71 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, | ||
72 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 | ||
73 | }; | ||
74 | |||
75 | 13 | static void gate_sha256_add(gate_sha256_t* context, unsigned char const* block) | |
76 | { | ||
77 | unsigned n; | ||
78 | unsigned long s0; | ||
79 | unsigned long s1; | ||
80 | unsigned long ch; | ||
81 | unsigned long temp1; | ||
82 | unsigned long temp2; | ||
83 | unsigned long maj; | ||
84 | |||
85 | 13 | unsigned long a = context->h0; | |
86 | 13 | unsigned long b = context->h1; | |
87 | 13 | unsigned long c = context->h2; | |
88 | 13 | unsigned long d = context->h3; | |
89 | 13 | unsigned long e = context->h4; | |
90 | 13 | unsigned long f = context->h5; | |
91 | 13 | unsigned long g = context->h6; | |
92 | 13 | unsigned long h = context->h7; | |
93 | |||
94 | unsigned long w[64]; | ||
95 | |||
96 |
2/2✓ Branch 0 taken 208 times.
✓ Branch 1 taken 13 times.
|
221 | for (n = 0; n != 16; ++n) |
97 | { | ||
98 | 208 | w[n] = uint32_load(&block[n * 4]); | |
99 | } | ||
100 | |||
101 |
2/2✓ Branch 0 taken 624 times.
✓ Branch 1 taken 13 times.
|
637 | for (n = 16; n < 64; ++n) |
102 | { | ||
103 | 624 | s0 = rotate_right32(w[n - 15], 7) ^ rotate_right32(w[n - 15], 18) ^ (w[n - 15] >> 3); | |
104 | 624 | s1 = rotate_right32(w[n - 2], 17) ^ rotate_right32(w[n - 2], 19) ^ (w[n - 2] >> 10); | |
105 | 624 | w[n] = (w[n - 16] + s0 + w[n - 7] + s1) & 0xffffffff; | |
106 | } | ||
107 | |||
108 |
2/2✓ Branch 0 taken 832 times.
✓ Branch 1 taken 13 times.
|
845 | for (n = 0; n < 64; ++n) |
109 | { | ||
110 | 832 | s1 = rotate_right32(e, 6) ^ rotate_right32(e, 11) ^ rotate_right32(e, 25); | |
111 | 832 | ch = (e & f) ^ ((~e) & g); | |
112 | 832 | temp1 = (h + s1 + ch + k[n] + w[n]) & 0xffffffff; | |
113 | 832 | s0 = rotate_right32(a, 2) ^ rotate_right32(a, 13) ^ rotate_right32(a, 22); | |
114 | 832 | maj = (a & b) ^ (a & c) ^ (b & c); | |
115 | 832 | temp2 = (s0 + maj) & 0xffffffff; | |
116 | |||
117 | 832 | h = g; | |
118 | 832 | g = f; | |
119 | 832 | f = e; | |
120 | 832 | e = (d + temp1) & 0xffffffff; | |
121 | 832 | d = c; | |
122 | 832 | c = b; | |
123 | 832 | b = a; | |
124 | 832 | a = (temp1 + temp2) & 0xffffffff; | |
125 | } | ||
126 | |||
127 | 13 | context->h0 = (context->h0 + a) & 0xffffffff; | |
128 | 13 | context->h1 = (context->h1 + b) & 0xffffffff; | |
129 | 13 | context->h2 = (context->h2 + c) & 0xffffffff; | |
130 | 13 | context->h3 = (context->h3 + d) & 0xffffffff; | |
131 | 13 | context->h4 = (context->h4 + e) & 0xffffffff; | |
132 | 13 | context->h5 = (context->h5 + f) & 0xffffffff; | |
133 | 13 | context->h6 = (context->h6 + g) & 0xffffffff; | |
134 | 13 | context->h7 = (context->h7 + h) & 0xffffffff; | |
135 | 13 | } | |
136 | |||
137 | 8 | void gate_sha256_init(gate_sha256_t* context) | |
138 | { | ||
139 | 8 | context->h0 = 0x6a09e667; | |
140 | 8 | context->h1 = 0xbb67ae85; | |
141 | 8 | context->h2 = 0x3c6ef372; | |
142 | 8 | context->h3 = 0xa54ff53a; | |
143 | 8 | context->h4 = 0x510e527f; | |
144 | 8 | context->h5 = 0x9b05688c; | |
145 | 8 | context->h6 = 0x1f83d9ab; | |
146 | 8 | context->h7 = 0x5be0cd19; | |
147 | |||
148 | 8 | context->bufferused = 0; | |
149 | 8 | context->msglength = 0; | |
150 | 8 | } | |
151 | 7 | void gate_sha256_update(gate_sha256_t* context, void const* buffer, gate_size_t length) | |
152 | { | ||
153 | 7 | unsigned char const* ptr = (unsigned char const*)buffer; | |
154 | |||
155 | 7 | context->msglength += length; | |
156 | |||
157 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
|
7 | if (context->bufferused > 0) |
158 | { | ||
159 | 1 | gate_size_t freebytes = GATE_SHA256_BLOCK_LENGTH - context->bufferused; | |
160 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (length < freebytes) |
161 | { | ||
162 | ✗ | gate_mem_copy(&context->buffer[context->bufferused], ptr, length); | |
163 | ✗ | context->bufferused += length; | |
164 | ✗ | return; | |
165 | } | ||
166 | else | ||
167 | { | ||
168 | 1 | gate_mem_copy(&context->buffer[context->bufferused], ptr, freebytes); | |
169 | 1 | gate_sha256_add(context, &context->buffer[0]); | |
170 | 1 | context->bufferused = 0; | |
171 | 1 | ptr += freebytes; | |
172 | 1 | length -= freebytes; | |
173 | } | ||
174 | } | ||
175 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 7 times.
|
12 | while (length >= GATE_SHA256_BLOCK_LENGTH) |
176 | { | ||
177 | 5 | gate_sha256_add(context, ptr); | |
178 | 5 | ptr += GATE_SHA256_BLOCK_LENGTH; | |
179 | 5 | length -= GATE_SHA256_BLOCK_LENGTH; | |
180 | } | ||
181 |
1/2✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
|
7 | if (length > 0) |
182 | { | ||
183 | 7 | gate_mem_copy(context->buffer, ptr, length); | |
184 | 7 | context->bufferused = length; | |
185 | } | ||
186 | } | ||
187 | |||
188 | 7 | void gate_sha256_finish(gate_sha256_t* context, gate_sha256_result_t* result) | |
189 | { | ||
190 | 7 | gate_uint64_t bitlen = context->msglength * 8; | |
191 | 7 | unsigned long bitlen_high = (unsigned long)(bitlen >> 32) & 0xffffffff; | |
192 | 7 | unsigned long bitlen_low = (unsigned long)(bitlen & 0xffffffff); | |
193 | 7 | gate_size_t freebytes = (GATE_SHA256_BLOCK_LENGTH - context->bufferused - 1); | |
194 | 7 | context->buffer[context->bufferused++] = 0x80; | |
195 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | if (freebytes < 8) |
196 | { | ||
197 | ✗ | gate_mem_clear(&context->buffer[context->bufferused], freebytes); | |
198 | ✗ | gate_sha256_add(context, &context->buffer[0]); | |
199 | ✗ | freebytes = GATE_SHA256_BLOCK_LENGTH; | |
200 | ✗ | context->bufferused = 0; | |
201 | } | ||
202 | 7 | gate_mem_clear(&context->buffer[context->bufferused], GATE_SHA256_BLOCK_LENGTH - 8 - context->bufferused); | |
203 | 7 | uint32_save(bitlen_high, &context->buffer[GATE_SHA256_BLOCK_LENGTH - 8]); | |
204 | 7 | uint32_save(bitlen_low, &context->buffer[GATE_SHA256_BLOCK_LENGTH - 4]); | |
205 | |||
206 | 7 | gate_sha256_add(context, context->buffer); | |
207 | |||
208 | 7 | uint32_save(context->h0, &result->hash[0]); | |
209 | 7 | uint32_save(context->h1, &result->hash[4]); | |
210 | 7 | uint32_save(context->h2, &result->hash[8]); | |
211 | 7 | uint32_save(context->h3, &result->hash[12]); | |
212 | 7 | uint32_save(context->h4, &result->hash[16]); | |
213 | 7 | uint32_save(context->h5, &result->hash[20]); | |
214 | 7 | uint32_save(context->h6, &result->hash[24]); | |
215 | 7 | uint32_save(context->h7, &result->hash[28]); | |
216 | 7 | } | |
217 |