Coverage Report

Created: 2026-03-12 06:35

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Utilities/cmlibrhash/librhash/sha1.c
Line
Count
Source
1
/* sha1.c - an implementation of Secure Hash Algorithm 1 (SHA1)
2
 * based on RFC 3174.
3
 *
4
 * Copyright (c) 2008, Aleksey Kravchenko <rhash.admin@gmail.com>
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 <string.h>
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
void rhash_sha1_init(sha1_ctx* ctx)
28
0
{
29
0
  ctx->length = 0;
30
31
  /* initialize algorithm state */
32
0
  ctx->hash[0] = 0x67452301;
33
0
  ctx->hash[1] = 0xefcdab89;
34
0
  ctx->hash[2] = 0x98badcfe;
35
0
  ctx->hash[3] = 0x10325476;
36
0
  ctx->hash[4] = 0xc3d2e1f0;
37
0
}
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
0
#define CHO(X,Y,Z) (((X)&(Y))|((~(X))&(Z)))
47
0
#define PAR(X,Y,Z) ((X)^(Y)^(Z))
48
0
#define MAJ(X,Y,Z) (((X)&(Y))|((X)&(Z))|((Y)&(Z)))
49
50
0
#define ROUND_0(a,b,c,d,e, FF, k, w) e +=              FF(b,       c,           d    )+ROTL32(a,5)+k+w
51
0
#define ROUND_1(a,b,c,d,e, FF, k, w) e +=              FF(b,ROTL32(c,30),       d    )+ROTL32(a,5)+k+w
52
0
#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
0
#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
static void rhash_sha1_process_block(unsigned* hash, const unsigned* block)
64
0
{
65
0
  uint32_t      W[80];             /* Word sequence */
66
0
  uint32_t      A, B, C, D, E;     /* Word buffers */
67
68
69
0
  A = hash[0];
70
0
  B = hash[1];
71
0
  C = hash[2];
72
0
  D = hash[3];
73
0
  E = hash[4];
74
75
  /* 0..19 */
76
0
  W[ 0] = be2me_32(block[ 0]);
77
0
  ROUND_0(A,B,C,D,E, CHO, K0, W[ 0]);
78
0
  W[ 1] = be2me_32(block[ 1]);
79
0
  ROUND_1(E,A,B,C,D, CHO, K0, W[ 1]);
80
0
  W[ 2] = be2me_32(block[ 2]);
81
0
  ROUND_2(D,E,A,B,C, CHO, K0, W[ 2]);
82
0
  W[ 3] = be2me_32(block[ 3]);
83
0
  ROUND(C,D,E,A,B, CHO, K0, W[ 3]);
84
0
  W[ 4] = be2me_32(block[ 4]);
85
0
  ROUND(B,C,D,E,A, CHO, K0, W[ 4]);
86
87
0
  W[ 5] = be2me_32(block[ 5]);
88
0
  ROUND(A,B,C,D,E, CHO, K0, W[ 5]);
89
0
  W[ 6] = be2me_32(block[ 6]);
90
0
  ROUND(E,A,B,C,D, CHO, K0, W[ 6]);
91
0
  W[ 7] = be2me_32(block[ 7]);
92
0
  ROUND(D,E,A,B,C, CHO, K0, W[ 7]);
93
0
  W[ 8] = be2me_32(block[ 8]);
94
0
  ROUND(C,D,E,A,B, CHO, K0, W[ 8]);
95
0
  W[ 9] = be2me_32(block[ 9]);
96
0
  ROUND(B,C,D,E,A, CHO, K0, W[ 9]);
97
98
0
  W[10] = be2me_32(block[10]);
99
0
  ROUND(A,B,C,D,E, CHO, K0, W[10]);
100
0
  W[11] = be2me_32(block[11]);
101
0
  ROUND(E,A,B,C,D, CHO, K0, W[11]);
102
0
  W[12] = be2me_32(block[12]);
103
0
  ROUND(D,E,A,B,C, CHO, K0, W[12]);
104
0
  W[13] = be2me_32(block[13]);
105
0
  ROUND(C,D,E,A,B, CHO, K0, W[13]);
106
0
  W[14] = be2me_32(block[14]);
107
0
  ROUND(B,C,D,E,A, CHO, K0, W[14]);
108
109
0
  W[15] = be2me_32(block[15]);
110
0
  ROUND(A,B,C,D,E, CHO, K0, W[15]);
111
0
  W[16] = ROTL32(W[13] ^ W[ 8] ^ W[ 2] ^ W[ 0], 1);
112
0
  ROUND(E,A,B,C,D, CHO, K0, W[16]);
113
0
  W[17] = ROTL32(W[14] ^ W[ 9] ^ W[ 3] ^ W[ 1], 1);
114
0
  ROUND(D,E,A,B,C, CHO, K0, W[17]);
115
0
  W[18] = ROTL32(W[15] ^ W[10] ^ W[ 4] ^ W[ 2], 1);
116
0
  ROUND(C,D,E,A,B, CHO, K0, W[18]);
117
0
  W[19] = ROTL32(W[16] ^ W[11] ^ W[ 5] ^ W[ 3], 1);
118
0
  ROUND(B,C,D,E,A, CHO, K0, W[19]);
119
  /* 20..39 */
120
0
  W[20] = ROTL32(W[17] ^ W[12] ^ W[ 6] ^ W[ 4], 1);
121
0
  ROUND(A,B,C,D,E, PAR, K1, W[20]);
122
0
  W[21] = ROTL32(W[18] ^ W[13] ^ W[ 7] ^ W[ 5], 1);
123
0
  ROUND(E,A,B,C,D, PAR, K1, W[21]);
124
0
  W[22] = ROTL32(W[19] ^ W[14] ^ W[ 8] ^ W[ 6], 1);
125
0
  ROUND(D,E,A,B,C, PAR, K1, W[22]);
126
0
  W[23] = ROTL32(W[20] ^ W[15] ^ W[ 9] ^ W[ 7], 1);
127
0
  ROUND(C,D,E,A,B, PAR, K1, W[23]);
128
0
  W[24] = ROTL32(W[21] ^ W[16] ^ W[10] ^ W[ 8], 1);
129
0
  ROUND(B,C,D,E,A, PAR, K1, W[24]);
130
131
0
  W[25] = ROTL32(W[22] ^ W[17] ^ W[11] ^ W[ 9], 1);
132
0
  ROUND(A,B,C,D,E, PAR, K1, W[25]);
133
0
  W[26] = ROTL32(W[23] ^ W[18] ^ W[12] ^ W[10], 1);
134
0
  ROUND(E,A,B,C,D, PAR, K1, W[26]);
135
0
  W[27] = ROTL32(W[24] ^ W[19] ^ W[13] ^ W[11], 1);
136
0
  ROUND(D,E,A,B,C, PAR, K1, W[27]);
137
0
  W[28] = ROTL32(W[25] ^ W[20] ^ W[14] ^ W[12], 1);
138
0
  ROUND(C,D,E,A,B, PAR, K1, W[28]);
139
0
  W[29] = ROTL32(W[26] ^ W[21] ^ W[15] ^ W[13], 1);
140
0
  ROUND(B,C,D,E,A, PAR, K1, W[29]);
141
142
0
  W[30] = ROTL32(W[27] ^ W[22] ^ W[16] ^ W[14], 1);
143
0
  ROUND(A,B,C,D,E, PAR, K1, W[30]);
144
0
  W[31] = ROTL32(W[28] ^ W[23] ^ W[17] ^ W[15], 1);
145
0
  ROUND(E,A,B,C,D, PAR, K1, W[31]);
146
0
  W[32] = ROTL32(W[29] ^ W[24] ^ W[18] ^ W[16], 1);
147
0
  ROUND(D,E,A,B,C, PAR, K1, W[32]);
148
0
  W[33] = ROTL32(W[30] ^ W[25] ^ W[19] ^ W[17], 1);
149
0
  ROUND(C,D,E,A,B, PAR, K1, W[33]);
150
0
  W[34] = ROTL32(W[31] ^ W[26] ^ W[20] ^ W[18], 1);
151
0
  ROUND(B,C,D,E,A, PAR, K1, W[34]);
152
153
0
  W[35] = ROTL32(W[32] ^ W[27] ^ W[21] ^ W[19], 1);
154
0
  ROUND(A,B,C,D,E, PAR, K1, W[35]);
155
0
  W[36] = ROTL32(W[33] ^ W[28] ^ W[22] ^ W[20], 1);
156
0
  ROUND(E,A,B,C,D, PAR, K1, W[36]);
157
0
  W[37] = ROTL32(W[34] ^ W[29] ^ W[23] ^ W[21], 1);
158
0
  ROUND(D,E,A,B,C, PAR, K1, W[37]);
159
0
  W[38] = ROTL32(W[35] ^ W[30] ^ W[24] ^ W[22], 1);
160
0
  ROUND(C,D,E,A,B, PAR, K1, W[38]);
161
0
  W[39] = ROTL32(W[36] ^ W[31] ^ W[25] ^ W[23], 1);
162
0
  ROUND(B,C,D,E,A, PAR, K1, W[39]);
163
  /* 40..59 */
164
0
  W[40] = ROTL32(W[37] ^ W[32] ^ W[26] ^ W[24], 1);
165
0
  ROUND(A,B,C,D,E, MAJ, K2, W[40]);
166
0
  W[41] = ROTL32(W[38] ^ W[33] ^ W[27] ^ W[25], 1);
167
0
  ROUND(E,A,B,C,D, MAJ, K2, W[41]);
168
0
  W[42] = ROTL32(W[39] ^ W[34] ^ W[28] ^ W[26], 1);
169
0
  ROUND(D,E,A,B,C, MAJ, K2, W[42]);
170
0
  W[43] = ROTL32(W[40] ^ W[35] ^ W[29] ^ W[27], 1);
171
0
  ROUND(C,D,E,A,B, MAJ, K2, W[43]);
172
0
  W[44] = ROTL32(W[41] ^ W[36] ^ W[30] ^ W[28], 1);
173
0
  ROUND(B,C,D,E,A, MAJ, K2, W[44]);
174
175
0
  W[45] = ROTL32(W[42] ^ W[37] ^ W[31] ^ W[29], 1);
176
0
  ROUND(A,B,C,D,E, MAJ, K2, W[45]);
177
0
  W[46] = ROTL32(W[43] ^ W[38] ^ W[32] ^ W[30], 1);
178
0
  ROUND(E,A,B,C,D, MAJ, K2, W[46]);
179
0
  W[47] = ROTL32(W[44] ^ W[39] ^ W[33] ^ W[31], 1);
180
0
  ROUND(D,E,A,B,C, MAJ, K2, W[47]);
181
0
  W[48] = ROTL32(W[45] ^ W[40] ^ W[34] ^ W[32], 1);
182
0
  ROUND(C,D,E,A,B, MAJ, K2, W[48]);
183
0
  W[49] = ROTL32(W[46] ^ W[41] ^ W[35] ^ W[33], 1);
184
0
  ROUND(B,C,D,E,A, MAJ, K2, W[49]);
185
186
0
  W[50] = ROTL32(W[47] ^ W[42] ^ W[36] ^ W[34], 1);
187
0
  ROUND(A,B,C,D,E, MAJ, K2, W[50]);
188
0
  W[51] = ROTL32(W[48] ^ W[43] ^ W[37] ^ W[35], 1);
189
0
  ROUND(E,A,B,C,D, MAJ, K2, W[51]);
190
0
  W[52] = ROTL32(W[49] ^ W[44] ^ W[38] ^ W[36], 1);
191
0
  ROUND(D,E,A,B,C, MAJ, K2, W[52]);
192
0
  W[53] = ROTL32(W[50] ^ W[45] ^ W[39] ^ W[37], 1);
193
0
  ROUND(C,D,E,A,B, MAJ, K2, W[53]);
194
0
  W[54] = ROTL32(W[51] ^ W[46] ^ W[40] ^ W[38], 1);
195
0
  ROUND(B,C,D,E,A, MAJ, K2, W[54]);
196
197
0
  W[55] = ROTL32(W[52] ^ W[47] ^ W[41] ^ W[39], 1);
198
0
  ROUND(A,B,C,D,E, MAJ, K2, W[55]);
199
0
  W[56] = ROTL32(W[53] ^ W[48] ^ W[42] ^ W[40], 1);
200
0
  ROUND(E,A,B,C,D, MAJ, K2, W[56]);
201
0
  W[57] = ROTL32(W[54] ^ W[49] ^ W[43] ^ W[41], 1);
202
0
  ROUND(D,E,A,B,C, MAJ, K2, W[57]);
203
0
  W[58] = ROTL32(W[55] ^ W[50] ^ W[44] ^ W[42], 1);
204
0
  ROUND(C,D,E,A,B, MAJ, K2, W[58]);
205
0
  W[59] = ROTL32(W[56] ^ W[51] ^ W[45] ^ W[43], 1);
206
0
  ROUND(B,C,D,E,A, MAJ, K2, W[59]);
207
  /* 60..79 */
208
0
  W[60] = ROTL32(W[57] ^ W[52] ^ W[46] ^ W[44], 1);
209
0
  ROUND(A,B,C,D,E, PAR, K3, W[60]);
210
0
  W[61] = ROTL32(W[58] ^ W[53] ^ W[47] ^ W[45], 1);
211
0
  ROUND(E,A,B,C,D, PAR, K3, W[61]);
212
0
  W[62] = ROTL32(W[59] ^ W[54] ^ W[48] ^ W[46], 1);
213
0
  ROUND(D,E,A,B,C, PAR, K3, W[62]);
214
0
  W[63] = ROTL32(W[60] ^ W[55] ^ W[49] ^ W[47], 1);
215
0
  ROUND(C,D,E,A,B, PAR, K3, W[63]);
216
0
  W[64] = ROTL32(W[61] ^ W[56] ^ W[50] ^ W[48], 1);
217
0
  ROUND(B,C,D,E,A, PAR, K3, W[64]);
218
219
0
  W[65] = ROTL32(W[62] ^ W[57] ^ W[51] ^ W[49], 1);
220
0
  ROUND(A,B,C,D,E, PAR, K3, W[65]);
221
0
  W[66] = ROTL32(W[63] ^ W[58] ^ W[52] ^ W[50], 1);
222
0
  ROUND(E,A,B,C,D, PAR, K3, W[66]);
223
0
  W[67] = ROTL32(W[64] ^ W[59] ^ W[53] ^ W[51], 1);
224
0
  ROUND(D,E,A,B,C, PAR, K3, W[67]);
225
0
  W[68] = ROTL32(W[65] ^ W[60] ^ W[54] ^ W[52], 1);
226
0
  ROUND(C,D,E,A,B, PAR, K3, W[68]);
227
0
  W[69] = ROTL32(W[66] ^ W[61] ^ W[55] ^ W[53], 1);
228
0
  ROUND(B,C,D,E,A, PAR, K3, W[69]);
229
230
0
  W[70] = ROTL32(W[67] ^ W[62] ^ W[56] ^ W[54], 1);
231
0
  ROUND(A,B,C,D,E, PAR, K3, W[70]);
232
0
  W[71] = ROTL32(W[68] ^ W[63] ^ W[57] ^ W[55], 1);
233
0
  ROUND(E,A,B,C,D, PAR, K3, W[71]);
234
0
  W[72] = ROTL32(W[69] ^ W[64] ^ W[58] ^ W[56], 1);
235
0
  ROUND(D,E,A,B,C, PAR, K3, W[72]);
236
0
  W[73] = ROTL32(W[70] ^ W[65] ^ W[59] ^ W[57], 1);
237
0
  ROUND(C,D,E,A,B, PAR, K3, W[73]);
238
0
  W[74] = ROTL32(W[71] ^ W[66] ^ W[60] ^ W[58], 1);
239
0
  ROUND(B,C,D,E,A, PAR, K3, W[74]);
240
241
0
  W[75] = ROTL32(W[72] ^ W[67] ^ W[61] ^ W[59], 1);
242
0
  ROUND(A,B,C,D,E, PAR, K3, W[75]);
243
0
  W[76] = ROTL32(W[73] ^ W[68] ^ W[62] ^ W[60], 1);
244
0
  ROUND(E,A,B,C,D, PAR, K3, W[76]);
245
0
  W[77] = ROTL32(W[74] ^ W[69] ^ W[63] ^ W[61], 1);
246
0
  ROUND(D,E,A,B,C, PAR, K3, W[77]);
247
0
  W[78] = ROTL32(W[75] ^ W[70] ^ W[64] ^ W[62], 1);
248
0
  ROUND(C,D,E,A,B, PAR, K3, W[78]);
249
0
  W[79] = ROTL32(W[76] ^ W[71] ^ W[65] ^ W[63], 1);
250
0
  ROUND(B,C,D,E,A, PAR, K3, W[79]);
251
252
253
0
  hash[0] += A;
254
0
  hash[1] += B;
255
0
  hash[2] += ROTL32(C,30);
256
0
  hash[3] += ROTL32(D,30);
257
0
  hash[4] += ROTL32(E,30);
258
0
}
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
void rhash_sha1_update(sha1_ctx* ctx, const unsigned char* msg, size_t size)
269
0
{
270
0
  unsigned index = (unsigned)ctx->length & 63;
271
0
  ctx->length += size;
272
273
  /* fill partial block */
274
0
  if (index) {
275
0
    unsigned left = sha1_block_size - index;
276
0
    memcpy(ctx->message + index, msg, (size < left ? size : left));
277
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
0
  }
284
0
  while (size >= sha1_block_size) {
285
0
    unsigned* aligned_message_block;
286
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
0
    } else {
291
0
      memcpy(ctx->message, msg, sha1_block_size);
292
0
      aligned_message_block = (unsigned*)ctx->message;
293
0
    }
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
0
  }
299
0
  if (size) {
300
    /* save leftovers */
301
0
    memcpy(ctx->message, msg, size);
302
0
  }
303
0
}
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
void rhash_sha1_final(sha1_ctx* ctx, unsigned char* result)
312
0
{
313
0
  unsigned  index = (unsigned)ctx->length & 63;
314
0
  unsigned* msg32 = (unsigned*)ctx->message;
315
316
  /* pad message and run for last block */
317
0
  ctx->message[index++] = 0x80;
318
0
  while ((index & 3) != 0) {
319
0
    ctx->message[index++] = 0;
320
0
  }
321
0
  index >>= 2;
322
323
  /* if no room left in the message to store 64-bit message length */
324
0
  if (index > 14) {
325
    /* then fill the rest with zeros and process it */
326
0
    while (index < 16) {
327
0
      msg32[index++] = 0;
328
0
    }
329
0
    rhash_sha1_process_block(ctx->hash, msg32);
330
0
    index = 0;
331
0
  }
332
0
  while (index < 14) {
333
0
    msg32[index++] = 0;
334
0
  }
335
0
  msg32[14] = be2me_32( (unsigned)(ctx->length >> 29) );
336
0
  msg32[15] = be2me_32( (unsigned)(ctx->length << 3) );
337
0
  rhash_sha1_process_block(ctx->hash, msg32);
338
339
0
  if (result) be32_copy(result, 0, &ctx->hash, sha1_hash_size);
340
0
}