Coverage Report

Created: 2025-10-13 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/njs/external/njs_sha2.c
Line
Count
Source
1
2
/*
3
 * Copyright (C) Dmitry Volyntsev
4
 * Copyright (C) NGINX, Inc.
5
 *
6
 * An internal SHA2 implementation.
7
 */
8
9
10
#include <njs_unix.h>
11
#include <njs_types.h>
12
#include <njs_clang.h>
13
#include <njs_str.h>
14
#include "njs_hash.h"
15
16
17
static const u_char *njs_sha2_body(njs_hash_t *ctx, const u_char *data,
18
    size_t size);
19
20
21
void
22
njs_sha2_init(njs_hash_t *ctx)
23
0
{
24
0
    ctx->a = 0x6a09e667;
25
0
    ctx->b = 0xbb67ae85;
26
0
    ctx->c = 0x3c6ef372;
27
0
    ctx->d = 0xa54ff53a;
28
0
    ctx->e = 0x510e527f;
29
0
    ctx->f = 0x9b05688c;
30
0
    ctx->g = 0x1f83d9ab;
31
0
    ctx->h = 0x5be0cd19;
32
33
0
    ctx->bytes = 0;
34
0
}
35
36
37
void
38
njs_sha2_update(njs_hash_t *ctx, const void *data, size_t size)
39
0
{
40
0
    size_t  used, free;
41
42
0
    used = (size_t) (ctx->bytes & 0x3f);
43
0
    ctx->bytes += size;
44
45
0
    if (used) {
46
0
        free = 64 - used;
47
48
0
        if (size < free) {
49
0
            memcpy(&ctx->buffer[used], data, size);
50
0
            return;
51
0
        }
52
53
0
        memcpy(&ctx->buffer[used], data, free);
54
0
        data = (u_char *) data + free;
55
0
        size -= free;
56
0
        (void) njs_sha2_body(ctx, ctx->buffer, 64);
57
0
    }
58
59
0
    if (size >= 64) {
60
0
        data = njs_sha2_body(ctx, data, size & ~(size_t) 0x3f);
61
0
        size &= 0x3f;
62
0
    }
63
64
0
    memcpy(ctx->buffer, data, size);
65
0
}
66
67
68
void
69
njs_sha2_final(u_char result[32], njs_hash_t *ctx)
70
0
{
71
0
    size_t  used, free;
72
73
0
    used = (size_t) (ctx->bytes & 0x3f);
74
75
0
    ctx->buffer[used++] = 0x80;
76
77
0
    free = 64 - used;
78
79
0
    if (free < 8) {
80
0
        njs_memzero(&ctx->buffer[used], free);
81
0
        (void) njs_sha2_body(ctx, ctx->buffer, 64);
82
0
        used = 0;
83
0
        free = 64;
84
0
    }
85
86
0
    njs_memzero(&ctx->buffer[used], free - 8);
87
88
0
    ctx->bytes <<= 3;
89
0
    ctx->buffer[56] = (u_char) (ctx->bytes >> 56);
90
0
    ctx->buffer[57] = (u_char) (ctx->bytes >> 48);
91
0
    ctx->buffer[58] = (u_char) (ctx->bytes >> 40);
92
0
    ctx->buffer[59] = (u_char) (ctx->bytes >> 32);
93
0
    ctx->buffer[60] = (u_char) (ctx->bytes >> 24);
94
0
    ctx->buffer[61] = (u_char) (ctx->bytes >> 16);
95
0
    ctx->buffer[62] = (u_char) (ctx->bytes >> 8);
96
0
    ctx->buffer[63] = (u_char)  ctx->bytes;
97
98
0
    (void) njs_sha2_body(ctx, ctx->buffer, 64);
99
100
0
    result[0]  = (u_char) (ctx->a >> 24);
101
0
    result[1]  = (u_char) (ctx->a >> 16);
102
0
    result[2]  = (u_char) (ctx->a >> 8);
103
0
    result[3]  = (u_char)  ctx->a;
104
0
    result[4]  = (u_char) (ctx->b >> 24);
105
0
    result[5]  = (u_char) (ctx->b >> 16);
106
0
    result[6]  = (u_char) (ctx->b >> 8);
107
0
    result[7]  = (u_char)  ctx->b;
108
0
    result[8]  = (u_char) (ctx->c >> 24);
109
0
    result[9]  = (u_char) (ctx->c >> 16);
110
0
    result[10] = (u_char) (ctx->c >> 8);
111
0
    result[11] = (u_char)  ctx->c;
112
0
    result[12] = (u_char) (ctx->d >> 24);
113
0
    result[13] = (u_char) (ctx->d >> 16);
114
0
    result[14] = (u_char) (ctx->d >> 8);
115
0
    result[15] = (u_char)  ctx->d;
116
0
    result[16] = (u_char) (ctx->e >> 24);
117
0
    result[17] = (u_char) (ctx->e >> 16);
118
0
    result[18] = (u_char) (ctx->e >> 8);
119
0
    result[19] = (u_char)  ctx->e;
120
0
    result[20] = (u_char) (ctx->f >> 24);
121
0
    result[21] = (u_char) (ctx->f >> 16);
122
0
    result[22] = (u_char) (ctx->f >> 8);
123
0
    result[23] = (u_char)  ctx->f;
124
0
    result[24] = (u_char) (ctx->g >> 24);
125
0
    result[25] = (u_char) (ctx->g >> 16);
126
0
    result[26] = (u_char) (ctx->g >> 8);
127
0
    result[27] = (u_char)  ctx->g;
128
0
    result[28] = (u_char) (ctx->h >> 24);
129
0
    result[29] = (u_char) (ctx->h >> 16);
130
0
    result[30] = (u_char) (ctx->h >> 8);
131
0
    result[31] = (u_char)  ctx->h;
132
133
0
    njs_explicit_memzero(ctx, sizeof(*ctx));
134
0
}
135
136
137
/*
138
 * Helper functions.
139
 */
140
141
0
#define ROTATE(bits, word)  (((word) >> (bits)) | ((word) << (32 - (bits))))
142
143
0
#define S0(a) (ROTATE(2, a) ^ ROTATE(13, a) ^ ROTATE(22, a))
144
0
#define S1(e) (ROTATE(6, e) ^ ROTATE(11, e) ^ ROTATE(25, e))
145
0
#define CH(e, f, g) (((e) & (f)) ^ ((~(e)) & (g)))
146
0
#define MAJ(a, b, c) (((a) & (b)) ^ ((a) & (c)) ^ ((b) & (c)))
147
148
#define STEP(a, b, c, d, e, f, g, h, w, k)                                    \
149
0
    temp1 = (h) + S1(e) + CH(e, f, g) + (k) + (w);                            \
150
0
    temp2 = S0(a) + MAJ(a, b, c);                                             \
151
0
    (h) = (g);                                                                \
152
0
    (g) = (f);                                                                \
153
0
    (f) = (e);                                                                \
154
0
    (e) = (d) + temp1;                                                        \
155
0
    (d) = (c);                                                                \
156
0
    (c) = (b);                                                                \
157
0
    (b) = (a);                                                                \
158
0
    (a) = temp1 + temp2;
159
160
161
/*
162
 * GET() reads 4 input bytes in big-endian byte order and returns
163
 * them as uint32_t.
164
 */
165
166
#define GET(n)                                                                \
167
0
    (  ((uint32_t) p[n * 4 + 3])                                              \
168
0
     | ((uint32_t) p[n * 4 + 2] << 8)                                         \
169
0
     | ((uint32_t) p[n * 4 + 1] << 16)                                        \
170
0
     | ((uint32_t) p[n * 4]     << 24))
171
172
173
/*
174
 * This processes one or more 64-byte data blocks, but does not update
175
 * the bit counters.  There are no alignment requirements.
176
 */
177
178
static const u_char *
179
njs_sha2_body(njs_hash_t *ctx, const u_char *data, size_t size)
180
0
{
181
0
    uint32_t       a, b, c, d, e, f, g, h, s0, s1, temp1, temp2;
182
0
    uint32_t       saved_a, saved_b, saved_c, saved_d, saved_e, saved_f,
183
0
                   saved_g, saved_h;
184
0
    uint32_t       words[64];
185
0
    njs_uint_t     i;
186
0
    const u_char  *p;
187
188
0
    p = data;
189
190
0
    a = ctx->a;
191
0
    b = ctx->b;
192
0
    c = ctx->c;
193
0
    d = ctx->d;
194
0
    e = ctx->e;
195
0
    f = ctx->f;
196
0
    g = ctx->g;
197
0
    h = ctx->h;
198
199
0
    do {
200
0
        saved_a = a;
201
0
        saved_b = b;
202
0
        saved_c = c;
203
0
        saved_d = d;
204
0
        saved_e = e;
205
0
        saved_f = f;
206
0
        saved_g = g;
207
0
        saved_h = h;
208
209
        /* Load data block into the words array */
210
211
0
        for (i = 0; i < 16; i++) {
212
0
            words[i] = GET(i);
213
0
        }
214
215
0
        for (i = 16; i < 64; i++) {
216
0
            s0 = ROTATE(7, words[i - 15])
217
0
                 ^ ROTATE(18, words[i - 15])
218
0
                 ^ (words[i - 15] >> 3);
219
220
0
            s1 = ROTATE(17, words[i - 2])
221
0
                 ^ ROTATE(19, words[i - 2])
222
0
                 ^ (words[i - 2] >> 10);
223
224
0
            words[i] = words[i - 16] + s0 + words[i - 7] + s1;
225
0
        }
226
227
        /* Transformations */
228
229
0
        STEP(a, b, c, d, e, f, g, h, words[0],  0x428a2f98);
230
0
        STEP(a, b, c, d, e, f, g, h, words[1],  0x71374491);
231
0
        STEP(a, b, c, d, e, f, g, h, words[2],  0xb5c0fbcf);
232
0
        STEP(a, b, c, d, e, f, g, h, words[3],  0xe9b5dba5);
233
0
        STEP(a, b, c, d, e, f, g, h, words[4],  0x3956c25b);
234
0
        STEP(a, b, c, d, e, f, g, h, words[5],  0x59f111f1);
235
0
        STEP(a, b, c, d, e, f, g, h, words[6],  0x923f82a4);
236
0
        STEP(a, b, c, d, e, f, g, h, words[7],  0xab1c5ed5);
237
0
        STEP(a, b, c, d, e, f, g, h, words[8],  0xd807aa98);
238
0
        STEP(a, b, c, d, e, f, g, h, words[9],  0x12835b01);
239
0
        STEP(a, b, c, d, e, f, g, h, words[10], 0x243185be);
240
0
        STEP(a, b, c, d, e, f, g, h, words[11], 0x550c7dc3);
241
0
        STEP(a, b, c, d, e, f, g, h, words[12], 0x72be5d74);
242
0
        STEP(a, b, c, d, e, f, g, h, words[13], 0x80deb1fe);
243
0
        STEP(a, b, c, d, e, f, g, h, words[14], 0x9bdc06a7);
244
0
        STEP(a, b, c, d, e, f, g, h, words[15], 0xc19bf174);
245
246
0
        STEP(a, b, c, d, e, f, g, h, words[16], 0xe49b69c1);
247
0
        STEP(a, b, c, d, e, f, g, h, words[17], 0xefbe4786);
248
0
        STEP(a, b, c, d, e, f, g, h, words[18], 0x0fc19dc6);
249
0
        STEP(a, b, c, d, e, f, g, h, words[19], 0x240ca1cc);
250
0
        STEP(a, b, c, d, e, f, g, h, words[20], 0x2de92c6f);
251
0
        STEP(a, b, c, d, e, f, g, h, words[21], 0x4a7484aa);
252
0
        STEP(a, b, c, d, e, f, g, h, words[22], 0x5cb0a9dc);
253
0
        STEP(a, b, c, d, e, f, g, h, words[23], 0x76f988da);
254
0
        STEP(a, b, c, d, e, f, g, h, words[24], 0x983e5152);
255
0
        STEP(a, b, c, d, e, f, g, h, words[25], 0xa831c66d);
256
0
        STEP(a, b, c, d, e, f, g, h, words[26], 0xb00327c8);
257
0
        STEP(a, b, c, d, e, f, g, h, words[27], 0xbf597fc7);
258
0
        STEP(a, b, c, d, e, f, g, h, words[28], 0xc6e00bf3);
259
0
        STEP(a, b, c, d, e, f, g, h, words[29], 0xd5a79147);
260
0
        STEP(a, b, c, d, e, f, g, h, words[30], 0x06ca6351);
261
0
        STEP(a, b, c, d, e, f, g, h, words[31], 0x14292967);
262
263
0
        STEP(a, b, c, d, e, f, g, h, words[32], 0x27b70a85);
264
0
        STEP(a, b, c, d, e, f, g, h, words[33], 0x2e1b2138);
265
0
        STEP(a, b, c, d, e, f, g, h, words[34], 0x4d2c6dfc);
266
0
        STEP(a, b, c, d, e, f, g, h, words[35], 0x53380d13);
267
0
        STEP(a, b, c, d, e, f, g, h, words[36], 0x650a7354);
268
0
        STEP(a, b, c, d, e, f, g, h, words[37], 0x766a0abb);
269
0
        STEP(a, b, c, d, e, f, g, h, words[38], 0x81c2c92e);
270
0
        STEP(a, b, c, d, e, f, g, h, words[39], 0x92722c85);
271
0
        STEP(a, b, c, d, e, f, g, h, words[40], 0xa2bfe8a1);
272
0
        STEP(a, b, c, d, e, f, g, h, words[41], 0xa81a664b);
273
0
        STEP(a, b, c, d, e, f, g, h, words[42], 0xc24b8b70);
274
0
        STEP(a, b, c, d, e, f, g, h, words[43], 0xc76c51a3);
275
0
        STEP(a, b, c, d, e, f, g, h, words[44], 0xd192e819);
276
0
        STEP(a, b, c, d, e, f, g, h, words[45], 0xd6990624);
277
0
        STEP(a, b, c, d, e, f, g, h, words[46], 0xf40e3585);
278
0
        STEP(a, b, c, d, e, f, g, h, words[47], 0x106aa070);
279
280
0
        STEP(a, b, c, d, e, f, g, h, words[48], 0x19a4c116);
281
0
        STEP(a, b, c, d, e, f, g, h, words[49], 0x1e376c08);
282
0
        STEP(a, b, c, d, e, f, g, h, words[50], 0x2748774c);
283
0
        STEP(a, b, c, d, e, f, g, h, words[51], 0x34b0bcb5);
284
0
        STEP(a, b, c, d, e, f, g, h, words[52], 0x391c0cb3);
285
0
        STEP(a, b, c, d, e, f, g, h, words[53], 0x4ed8aa4a);
286
0
        STEP(a, b, c, d, e, f, g, h, words[54], 0x5b9cca4f);
287
0
        STEP(a, b, c, d, e, f, g, h, words[55], 0x682e6ff3);
288
0
        STEP(a, b, c, d, e, f, g, h, words[56], 0x748f82ee);
289
0
        STEP(a, b, c, d, e, f, g, h, words[57], 0x78a5636f);
290
0
        STEP(a, b, c, d, e, f, g, h, words[58], 0x84c87814);
291
0
        STEP(a, b, c, d, e, f, g, h, words[59], 0x8cc70208);
292
0
        STEP(a, b, c, d, e, f, g, h, words[60], 0x90befffa);
293
0
        STEP(a, b, c, d, e, f, g, h, words[61], 0xa4506ceb);
294
0
        STEP(a, b, c, d, e, f, g, h, words[62], 0xbef9a3f7);
295
0
        STEP(a, b, c, d, e, f, g, h, words[63], 0xc67178f2);
296
297
0
        a += saved_a;
298
0
        b += saved_b;
299
0
        c += saved_c;
300
0
        d += saved_d;
301
0
        e += saved_e;
302
0
        f += saved_f;
303
0
        g += saved_g;
304
0
        h += saved_h;
305
306
0
        p += 64;
307
308
0
    } while (size -= 64);
309
310
0
    ctx->a = a;
311
0
    ctx->b = b;
312
0
    ctx->c = c;
313
0
    ctx->d = d;
314
0
    ctx->e = e;
315
0
    ctx->f = f;
316
0
    ctx->g = g;
317
0
    ctx->h = h;
318
319
0
    return p;
320
0
}