GCC Code Coverage Report


Directory: src/gate/
File: src/gate/encode/sha256hash.c
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 102 109 93.6%
Functions: 7 7 100.0%
Branches: 13 16 81.2%

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 336 static unsigned long uint32_load(unsigned char const* buffer)
35 {
36 336 return (((unsigned long)buffer[0] & 0xff) << 24)
37 336 | (((unsigned long)buffer[1] & 0xff) << 16)
38 336 | (((unsigned long)buffer[2] & 0xff) << 8)
39 336 | (((unsigned long)buffer[3] & 0xff))
40 ;
41 }
42
43 110 static void uint32_save(unsigned long value, unsigned char* buffer)
44 {
45 110 buffer[0] = (unsigned char)((value >> 24) & 0xff);
46 110 buffer[1] = (unsigned char)((value >> 16) & 0xff);
47 110 buffer[2] = (unsigned char)((value >> 8) & 0xff);
48 110 buffer[3] = (unsigned char)((value) & 0xff);
49 110 }
50
51 12096 static unsigned long rotate_right32(unsigned long value, unsigned n)
52 {
53 12096 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 21 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
81 21 unsigned long a = context->h0;
82 21 unsigned long b = context->h1;
83 21 unsigned long c = context->h2;
84 21 unsigned long d = context->h3;
85 21 unsigned long e = context->h4;
86 21 unsigned long f = context->h5;
87 21 unsigned long g = context->h6;
88 21 unsigned long h = context->h7;
89
90 unsigned long w[64];
91
92
2/2
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 21 times.
357 for (n = 0; n != 16; ++n)
93 {
94 336 w[n] = uint32_load(&block[n * 4]);
95 }
96
97
2/2
✓ Branch 0 taken 1008 times.
✓ Branch 1 taken 21 times.
1029 for (n = 16; n < 64; ++n)
98 {
99 1008 s0 = rotate_right32(w[n - 15], 7) ^ rotate_right32(w[n - 15], 18) ^ (w[n - 15] >> 3);
100 1008 s1 = rotate_right32(w[n - 2], 17) ^ rotate_right32(w[n - 2], 19) ^ (w[n - 2] >> 10);
101 1008 w[n] = (w[n - 16] + s0 + w[n - 7] + s1) & 0xffffffff;
102 }
103
104
2/2
✓ Branch 0 taken 1344 times.
✓ Branch 1 taken 21 times.
1365 for (n = 0; n < 64; ++n)
105 {
106 unsigned long ch;
107 unsigned long temp1;
108 unsigned long temp2;
109 unsigned long maj;
110
111 1344 s1 = rotate_right32(e, 6) ^ rotate_right32(e, 11) ^ rotate_right32(e, 25);
112 1344 ch = (e & f) ^ ((~e) & g);
113 1344 temp1 = (h + s1 + ch + k[n] + w[n]) & 0xffffffff;
114 1344 s0 = rotate_right32(a, 2) ^ rotate_right32(a, 13) ^ rotate_right32(a, 22);
115 1344 maj = (a & b) ^ (a & c) ^ (b & c);
116 1344 temp2 = (s0 + maj) & 0xffffffff;
117
118 1344 h = g;
119 1344 g = f;
120 1344 f = e;
121 1344 e = (d + temp1) & 0xffffffff;
122 1344 d = c;
123 1344 c = b;
124 1344 b = a;
125 1344 a = (temp1 + temp2) & 0xffffffff;
126 }
127
128 21 context->h0 = (context->h0 + a) & 0xffffffff;
129 21 context->h1 = (context->h1 + b) & 0xffffffff;
130 21 context->h2 = (context->h2 + c) & 0xffffffff;
131 21 context->h3 = (context->h3 + d) & 0xffffffff;
132 21 context->h4 = (context->h4 + e) & 0xffffffff;
133 21 context->h5 = (context->h5 + f) & 0xffffffff;
134 21 context->h6 = (context->h6 + g) & 0xffffffff;
135 21 context->h7 = (context->h7 + h) & 0xffffffff;
136 21 }
137
138 13 void gate_sha256_init(gate_sha256_t* context)
139 {
140 13 context->h0 = 0x6a09e667;
141 13 context->h1 = 0xbb67ae85;
142 13 context->h2 = 0x3c6ef372;
143 13 context->h3 = 0xa54ff53a;
144 13 context->h4 = 0x510e527f;
145 13 context->h5 = 0x9b05688c;
146 13 context->h6 = 0x1f83d9ab;
147 13 context->h7 = 0x5be0cd19;
148
149 13 context->bufferused = 0;
150 13 context->msglength = 0;
151 13 }
152 11 void gate_sha256_update(gate_sha256_t* context, void const* buffer, gate_size_t length)
153 {
154 11 unsigned char const* ptr = (unsigned char const*)buffer;
155
156 11 context->msglength += length;
157
158
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10 times.
11 if (context->bufferused > 0)
159 {
160 1 gate_size_t freebytes = GATE_SHA256_BLOCK_LENGTH - context->bufferused;
161
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (length < freebytes)
162 {
163 gate_mem_copy(&context->buffer[context->bufferused], ptr, length);
164 context->bufferused += length;
165 return;
166 }
167 else
168 {
169 1 gate_mem_copy(&context->buffer[context->bufferused], ptr, freebytes);
170 1 gate_sha256_add(context, &context->buffer[0]);
171 1 context->bufferused = 0;
172 1 ptr += freebytes;
173 1 length -= freebytes;
174 }
175 }
176
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 11 times.
20 while (length >= GATE_SHA256_BLOCK_LENGTH)
177 {
178 9 gate_sha256_add(context, ptr);
179 9 ptr += GATE_SHA256_BLOCK_LENGTH;
180 9 length -= GATE_SHA256_BLOCK_LENGTH;
181 }
182
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (length > 0)
183 {
184 11 gate_mem_copy(context->buffer, ptr, length);
185 11 context->bufferused = length;
186 }
187 }
188
189 11 void gate_sha256_finish(gate_sha256_t* context, gate_sha256_result_t* result)
190 {
191 11 gate_uint64_t bitlen = context->msglength * 8;
192 11 unsigned long bitlen_high = (unsigned long)(bitlen >> 32) & 0xffffffff;
193 11 unsigned long bitlen_low = (unsigned long)(bitlen & 0xffffffff);
194 11 gate_size_t freebytes = (GATE_SHA256_BLOCK_LENGTH - context->bufferused - 1);
195 11 context->buffer[context->bufferused++] = 0x80;
196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (freebytes < 8)
197 {
198 gate_mem_clear(&context->buffer[context->bufferused], freebytes);
199 gate_sha256_add(context, &context->buffer[0]);
200 freebytes = GATE_SHA256_BLOCK_LENGTH;
201 context->bufferused = 0;
202 }
203 11 gate_mem_clear(&context->buffer[context->bufferused], GATE_SHA256_BLOCK_LENGTH - 8 - context->bufferused);
204 11 uint32_save(bitlen_high, &context->buffer[GATE_SHA256_BLOCK_LENGTH - 8]);
205 11 uint32_save(bitlen_low, &context->buffer[GATE_SHA256_BLOCK_LENGTH - 4]);
206
207 11 gate_sha256_add(context, context->buffer);
208
209 11 uint32_save(context->h0, &result->hash[0]);
210 11 uint32_save(context->h1, &result->hash[4]);
211 11 uint32_save(context->h2, &result->hash[8]);
212 11 uint32_save(context->h3, &result->hash[12]);
213 11 uint32_save(context->h4, &result->hash[16]);
214 11 uint32_save(context->h5, &result->hash[20]);
215 11 uint32_save(context->h6, &result->hash[24]);
216 11 uint32_save(context->h7, &result->hash[28]);
217 11 }
218