GCC Code Coverage Report


Directory: src/gate/
File: src/gate/encode/sha1hash.c
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 91 98 92.9%
Functions: 7 7 100.0%
Branches: 19 22 86.4%

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