Coverage Report

Created: 2025-12-14 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/krb5/src/lib/crypto/builtin/sha1/shs.c
Line
Count
Source
1
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
#include "shs.h"
3
#ifdef HAVE_SYS_TYPES_H
4
#include <sys/types.h>
5
#endif
6
#include <string.h>
7
8
#ifdef K5_BUILTIN_SHA1
9
10
/* The SHS f()-functions.  The f1 and f3 functions can be optimized to
11
   save one boolean operation each - thanks to Rich Schroeppel,
12
   rcs@cs.arizona.edu for discovering this */
13
14
431k
#define f1(x,y,z)   ( z ^ ( x & ( y ^ z ) ) )           /* Rounds  0-19 */
15
431k
#define f2(x,y,z)   ( x ^ y ^ z )                       /* Rounds 20-39 */
16
431k
#define f3(x,y,z)   ( ( x & y ) | ( z & ( x | y ) ) )   /* Rounds 40-59 */
17
431k
#define f4(x,y,z)   ( x ^ y ^ z )                       /* Rounds 60-79 */
18
19
/* The SHS Mysterious Constants */
20
21
#define K1  0x5A827999L                                 /* Rounds  0-19 */
22
#define K2  0x6ED9EBA1L                                 /* Rounds 20-39 */
23
#define K3  0x8F1BBCDCL                                 /* Rounds 40-59 */
24
#define K4  0xCA62C1D6L                                 /* Rounds 60-79 */
25
26
/* SHS initial values */
27
28
6.68k
#define h0init  0x67452301L
29
6.68k
#define h1init  0xEFCDAB89L
30
6.68k
#define h2init  0x98BADCFEL
31
6.68k
#define h3init  0x10325476L
32
6.68k
#define h4init  0xC3D2E1F0L
33
34
/* Note that it may be necessary to add parentheses to these macros if they
35
   are to be called with expressions as arguments */
36
37
/* 32-bit rotate left - kludged with shifts */
38
39
3.45M
#define ROTL(n,X)  ((((X) << (n)) & 0xffffffff) | ((X) >> (32 - n)))
40
41
/* The initial expanding function.  The hash function is defined over an
42
   80-word expanded input array W, where the first 16 are copies of the input
43
   data, and the remaining 64 are defined by
44
45
   W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
46
47
   This implementation generates these values on the fly in a circular
48
   buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
49
   optimization.
50
51
   The updated SHS changes the expanding function by adding a rotate of 1
52
   bit.  Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
53
   for this information */
54
55
#ifdef NEW_SHS
56
#define expand(W,i) ( W[ i & 15 ] = ROTL( 1, ( W[ i & 15 ] ^ W[ (i - 14) & 15 ] ^ \
57
                                               W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] )))
58
#else
59
#define expand(W,i) ( W[ i & 15 ] ^= W[ (i - 14) & 15 ] ^       \
60
                      W[ (i - 8) & 15 ] ^ W[ (i - 3) & 15 ] )
61
#endif /* NEW_SHS */
62
63
/* The prototype SHS sub-round.  The fundamental sub-round is:
64
65
   a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
66
   b' = a;
67
   c' = ROTL( 30, b );
68
   d' = c;
69
   e' = d;
70
71
   but this is implemented by unrolling the loop 5 times and renaming the
72
   variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
73
   This code is then replicated 20 times for each of the 4 functions, using
74
   the next 20 values from the W[] array each time */
75
76
#define subRound(a, b, c, d, e, f, k, data)             \
77
1.72M
    ( e += ROTL( 5, a ) + f( b, c, d ) + k + data,      \
78
1.72M
      e &= 0xffffffff, b = ROTL( 30, b ) )
79
80
/* Initialize the SHS values */
81
82
void shsInit(SHS_INFO *shsInfo)
83
6.68k
{
84
    /* Set the h-vars to their initial values */
85
6.68k
    shsInfo->digest[ 0 ] = h0init;
86
6.68k
    shsInfo->digest[ 1 ] = h1init;
87
6.68k
    shsInfo->digest[ 2 ] = h2init;
88
6.68k
    shsInfo->digest[ 3 ] = h3init;
89
6.68k
    shsInfo->digest[ 4 ] = h4init;
90
91
    /* Initialise bit count */
92
6.68k
    shsInfo->countLo = shsInfo->countHi = 0;
93
6.68k
}
94
95
/* Perform the SHS transformation.  Note that this code, like MD5, seems to
96
   break some optimizing compilers due to the complexity of the expressions
97
   and the size of the basic block.  It may be necessary to split it into
98
   sections, e.g. based on the four subrounds
99
100
   Note that this corrupts the shsInfo->data area */
101
102
static void SHSTransform (SHS_LONG *digest, const SHS_LONG *data);
103
104
static
105
void SHSTransform(SHS_LONG *digest, const SHS_LONG *data)
106
21.5k
{
107
21.5k
    SHS_LONG A, B, C, D, E;     /* Local vars */
108
21.5k
    SHS_LONG eData[ 16 ];       /* Expanded data */
109
110
    /* Set up first buffer and local data buffer */
111
21.5k
    A = digest[ 0 ];
112
21.5k
    B = digest[ 1 ];
113
21.5k
    C = digest[ 2 ];
114
21.5k
    D = digest[ 3 ];
115
21.5k
    E = digest[ 4 ];
116
21.5k
    memcpy(eData, data, sizeof (eData));
117
118
#if defined(CONFIG_SMALL) && !defined(CONFIG_SMALL_NO_CRYPTO)
119
120
    {
121
        int i;
122
        SHS_LONG temp;
123
        for (i = 0; i < 20; i++) {
124
            SHS_LONG x = (i < 16) ? eData[i] : expand(eData, i);
125
            subRound(A, B, C, D, E, f1, K1, x);
126
            temp = E, E = D, D = C, C = B, B = A, A = temp;
127
        }
128
        for (i = 20; i < 40; i++) {
129
            subRound(A, B, C, D, E, f2, K2, expand(eData, i));
130
            temp = E, E = D, D = C, C = B, B = A, A = temp;
131
        }
132
        for (i = 40; i < 60; i++) {
133
            subRound(A, B, C, D, E, f3, K3, expand(eData, i));
134
            temp = E, E = D, D = C, C = B, B = A, A = temp;
135
        }
136
        for (i = 60; i < 80; i++) {
137
            subRound(A, B, C, D, E, f4, K4, expand(eData, i));
138
            temp = E, E = D, D = C, C = B, B = A, A = temp;
139
        }
140
    }
141
142
#else
143
144
    /* Heavy mangling, in 4 sub-rounds of 20 iterations each. */
145
21.5k
    subRound( A, B, C, D, E, f1, K1, eData[  0 ] );
146
21.5k
    subRound( E, A, B, C, D, f1, K1, eData[  1 ] );
147
21.5k
    subRound( D, E, A, B, C, f1, K1, eData[  2 ] );
148
21.5k
    subRound( C, D, E, A, B, f1, K1, eData[  3 ] );
149
21.5k
    subRound( B, C, D, E, A, f1, K1, eData[  4 ] );
150
21.5k
    subRound( A, B, C, D, E, f1, K1, eData[  5 ] );
151
21.5k
    subRound( E, A, B, C, D, f1, K1, eData[  6 ] );
152
21.5k
    subRound( D, E, A, B, C, f1, K1, eData[  7 ] );
153
21.5k
    subRound( C, D, E, A, B, f1, K1, eData[  8 ] );
154
21.5k
    subRound( B, C, D, E, A, f1, K1, eData[  9 ] );
155
21.5k
    subRound( A, B, C, D, E, f1, K1, eData[ 10 ] );
156
21.5k
    subRound( E, A, B, C, D, f1, K1, eData[ 11 ] );
157
21.5k
    subRound( D, E, A, B, C, f1, K1, eData[ 12 ] );
158
21.5k
    subRound( C, D, E, A, B, f1, K1, eData[ 13 ] );
159
21.5k
    subRound( B, C, D, E, A, f1, K1, eData[ 14 ] );
160
21.5k
    subRound( A, B, C, D, E, f1, K1, eData[ 15 ] );
161
21.5k
    subRound( E, A, B, C, D, f1, K1, expand( eData, 16 ) );
162
21.5k
    subRound( D, E, A, B, C, f1, K1, expand( eData, 17 ) );
163
21.5k
    subRound( C, D, E, A, B, f1, K1, expand( eData, 18 ) );
164
21.5k
    subRound( B, C, D, E, A, f1, K1, expand( eData, 19 ) );
165
166
21.5k
    subRound( A, B, C, D, E, f2, K2, expand( eData, 20 ) );
167
21.5k
    subRound( E, A, B, C, D, f2, K2, expand( eData, 21 ) );
168
21.5k
    subRound( D, E, A, B, C, f2, K2, expand( eData, 22 ) );
169
21.5k
    subRound( C, D, E, A, B, f2, K2, expand( eData, 23 ) );
170
21.5k
    subRound( B, C, D, E, A, f2, K2, expand( eData, 24 ) );
171
21.5k
    subRound( A, B, C, D, E, f2, K2, expand( eData, 25 ) );
172
21.5k
    subRound( E, A, B, C, D, f2, K2, expand( eData, 26 ) );
173
21.5k
    subRound( D, E, A, B, C, f2, K2, expand( eData, 27 ) );
174
21.5k
    subRound( C, D, E, A, B, f2, K2, expand( eData, 28 ) );
175
21.5k
    subRound( B, C, D, E, A, f2, K2, expand( eData, 29 ) );
176
21.5k
    subRound( A, B, C, D, E, f2, K2, expand( eData, 30 ) );
177
21.5k
    subRound( E, A, B, C, D, f2, K2, expand( eData, 31 ) );
178
21.5k
    subRound( D, E, A, B, C, f2, K2, expand( eData, 32 ) );
179
21.5k
    subRound( C, D, E, A, B, f2, K2, expand( eData, 33 ) );
180
21.5k
    subRound( B, C, D, E, A, f2, K2, expand( eData, 34 ) );
181
21.5k
    subRound( A, B, C, D, E, f2, K2, expand( eData, 35 ) );
182
21.5k
    subRound( E, A, B, C, D, f2, K2, expand( eData, 36 ) );
183
21.5k
    subRound( D, E, A, B, C, f2, K2, expand( eData, 37 ) );
184
21.5k
    subRound( C, D, E, A, B, f2, K2, expand( eData, 38 ) );
185
21.5k
    subRound( B, C, D, E, A, f2, K2, expand( eData, 39 ) );
186
187
21.5k
    subRound( A, B, C, D, E, f3, K3, expand( eData, 40 ) );
188
21.5k
    subRound( E, A, B, C, D, f3, K3, expand( eData, 41 ) );
189
21.5k
    subRound( D, E, A, B, C, f3, K3, expand( eData, 42 ) );
190
21.5k
    subRound( C, D, E, A, B, f3, K3, expand( eData, 43 ) );
191
21.5k
    subRound( B, C, D, E, A, f3, K3, expand( eData, 44 ) );
192
21.5k
    subRound( A, B, C, D, E, f3, K3, expand( eData, 45 ) );
193
21.5k
    subRound( E, A, B, C, D, f3, K3, expand( eData, 46 ) );
194
21.5k
    subRound( D, E, A, B, C, f3, K3, expand( eData, 47 ) );
195
21.5k
    subRound( C, D, E, A, B, f3, K3, expand( eData, 48 ) );
196
21.5k
    subRound( B, C, D, E, A, f3, K3, expand( eData, 49 ) );
197
21.5k
    subRound( A, B, C, D, E, f3, K3, expand( eData, 50 ) );
198
21.5k
    subRound( E, A, B, C, D, f3, K3, expand( eData, 51 ) );
199
21.5k
    subRound( D, E, A, B, C, f3, K3, expand( eData, 52 ) );
200
21.5k
    subRound( C, D, E, A, B, f3, K3, expand( eData, 53 ) );
201
21.5k
    subRound( B, C, D, E, A, f3, K3, expand( eData, 54 ) );
202
21.5k
    subRound( A, B, C, D, E, f3, K3, expand( eData, 55 ) );
203
21.5k
    subRound( E, A, B, C, D, f3, K3, expand( eData, 56 ) );
204
21.5k
    subRound( D, E, A, B, C, f3, K3, expand( eData, 57 ) );
205
21.5k
    subRound( C, D, E, A, B, f3, K3, expand( eData, 58 ) );
206
21.5k
    subRound( B, C, D, E, A, f3, K3, expand( eData, 59 ) );
207
208
21.5k
    subRound( A, B, C, D, E, f4, K4, expand( eData, 60 ) );
209
21.5k
    subRound( E, A, B, C, D, f4, K4, expand( eData, 61 ) );
210
21.5k
    subRound( D, E, A, B, C, f4, K4, expand( eData, 62 ) );
211
21.5k
    subRound( C, D, E, A, B, f4, K4, expand( eData, 63 ) );
212
21.5k
    subRound( B, C, D, E, A, f4, K4, expand( eData, 64 ) );
213
21.5k
    subRound( A, B, C, D, E, f4, K4, expand( eData, 65 ) );
214
21.5k
    subRound( E, A, B, C, D, f4, K4, expand( eData, 66 ) );
215
21.5k
    subRound( D, E, A, B, C, f4, K4, expand( eData, 67 ) );
216
21.5k
    subRound( C, D, E, A, B, f4, K4, expand( eData, 68 ) );
217
21.5k
    subRound( B, C, D, E, A, f4, K4, expand( eData, 69 ) );
218
21.5k
    subRound( A, B, C, D, E, f4, K4, expand( eData, 70 ) );
219
21.5k
    subRound( E, A, B, C, D, f4, K4, expand( eData, 71 ) );
220
21.5k
    subRound( D, E, A, B, C, f4, K4, expand( eData, 72 ) );
221
21.5k
    subRound( C, D, E, A, B, f4, K4, expand( eData, 73 ) );
222
21.5k
    subRound( B, C, D, E, A, f4, K4, expand( eData, 74 ) );
223
21.5k
    subRound( A, B, C, D, E, f4, K4, expand( eData, 75 ) );
224
21.5k
    subRound( E, A, B, C, D, f4, K4, expand( eData, 76 ) );
225
21.5k
    subRound( D, E, A, B, C, f4, K4, expand( eData, 77 ) );
226
21.5k
    subRound( C, D, E, A, B, f4, K4, expand( eData, 78 ) );
227
21.5k
    subRound( B, C, D, E, A, f4, K4, expand( eData, 79 ) );
228
229
21.5k
#endif
230
231
    /* Build message digest */
232
21.5k
    digest[ 0 ] += A;
233
21.5k
    digest[ 0 ] &= 0xffffffff;
234
21.5k
    digest[ 1 ] += B;
235
21.5k
    digest[ 1 ] &= 0xffffffff;
236
21.5k
    digest[ 2 ] += C;
237
21.5k
    digest[ 2 ] &= 0xffffffff;
238
21.5k
    digest[ 3 ] += D;
239
21.5k
    digest[ 3 ] &= 0xffffffff;
240
21.5k
    digest[ 4 ] += E;
241
21.5k
    digest[ 4 ] &= 0xffffffff;
242
21.5k
}
243
244
/* Update SHS for a block of data */
245
246
void shsUpdate(SHS_INFO *shsInfo, const SHS_BYTE *buffer, unsigned int count)
247
14.3k
{
248
14.3k
    SHS_LONG tmp;
249
14.3k
    unsigned int dataCount;
250
14.3k
    int canfill;
251
14.3k
    SHS_LONG *lp;
252
253
    /* Update bitcount */
254
14.3k
    tmp = shsInfo->countLo;
255
14.3k
    shsInfo->countLo = tmp + (((SHS_LONG) count) << 3 );
256
14.3k
    if ((shsInfo->countLo &= 0xffffffff) < tmp)
257
0
        shsInfo->countHi++;     /* Carry from low to high */
258
14.3k
    shsInfo->countHi += count >> 29;
259
260
    /* Get count of bytes already in data */
261
14.3k
    dataCount = (tmp >> 3) & 0x3F;
262
263
    /* Handle any leading odd-sized chunks */
264
14.3k
    if (dataCount) {
265
1.84k
        lp = shsInfo->data + dataCount / 4;
266
1.84k
        dataCount = SHS_DATASIZE - dataCount;
267
1.84k
        canfill = (count >= dataCount);
268
269
1.84k
        if (dataCount % 4) {
270
            /* Fill out a full 32 bit word first if needed -- this
271
               is not very efficient (computed shift amount),
272
               but it shouldn't happen often. */
273
772
            while (dataCount % 4 && count > 0) {
274
227
                *lp |= (SHS_LONG) *buffer++ << ((--dataCount % 4) * 8);
275
227
                count--;
276
227
            }
277
545
            lp++;
278
545
        }
279
11.1k
        while (lp < shsInfo->data + 16) {
280
10.4k
            if (count < 4) {
281
1.15k
                *lp = 0;
282
1.15k
                switch (count % 4) {
283
57
                case 3:
284
57
                    *lp |= (SHS_LONG) buffer[2] << 8;
285
144
                case 2:
286
144
                    *lp |= (SHS_LONG) buffer[1] << 16;
287
196
                case 1:
288
196
                    *lp |= (SHS_LONG) buffer[0] << 24;
289
1.15k
                }
290
1.15k
                count = 0;
291
1.15k
                break;          /* out of while loop */
292
1.15k
            }
293
9.27k
            *lp++ = load_32_be(buffer);
294
9.27k
            buffer += 4;
295
9.27k
            count -= 4;
296
9.27k
        }
297
1.84k
        if (canfill) {
298
655
            SHSTransform(shsInfo->digest, shsInfo->data);
299
655
        }
300
1.84k
    }
301
302
    /* Process data in SHS_DATASIZE chunks */
303
28.0k
    while (count >= SHS_DATASIZE) {
304
13.6k
        lp = shsInfo->data;
305
232k
        while (lp < shsInfo->data + 16) {
306
218k
            *lp++ = load_32_be(buffer);
307
218k
            buffer += 4;
308
218k
        }
309
13.6k
        SHSTransform(shsInfo->digest, shsInfo->data);
310
13.6k
        count -= SHS_DATASIZE;
311
13.6k
    }
312
313
14.3k
    if (count > 0) {
314
7.18k
        lp = shsInfo->data;
315
44.1k
        while (count > 4) {
316
37.0k
            *lp++ = load_32_be(buffer);
317
37.0k
            buffer += 4;
318
37.0k
            count -= 4;
319
37.0k
        }
320
7.18k
        *lp = 0;
321
7.18k
        switch (count % 4) {
322
5.09k
        case 0:
323
5.09k
            *lp |= ((SHS_LONG) buffer[3]);
324
5.87k
        case 3:
325
5.87k
            *lp |= ((SHS_LONG) buffer[2]) << 8;
326
6.21k
        case 2:
327
6.21k
            *lp |= ((SHS_LONG) buffer[1]) << 16;
328
7.18k
        case 1:
329
7.18k
            *lp |= ((SHS_LONG) buffer[0]) << 24;
330
7.18k
        }
331
7.18k
    }
332
14.3k
}
333
334
/* Final wrapup - pad to SHS_DATASIZE-byte boundary with the bit pattern
335
   1 0* (64-bit count of bits processed, MSB-first) */
336
337
void shsFinal(SHS_INFO *shsInfo)
338
6.68k
{
339
6.68k
    int count;
340
6.68k
    SHS_LONG *lp;
341
342
    /* Compute number of bytes mod 64 */
343
6.68k
    count = (int) shsInfo->countLo;
344
6.68k
    count = (count >> 3) & 0x3F;
345
346
    /* Set the first char of padding to 0x80.  This is safe since there is
347
       always at least one byte free */
348
6.68k
    lp = shsInfo->data + count / 4;
349
6.68k
    switch (count % 4) {
350
800
    case 3:
351
800
        *lp++ |= (SHS_LONG) 0x80;
352
800
        break;
353
400
    case 2:
354
400
        *lp++ |= (SHS_LONG) 0x80 << 8;
355
400
        break;
356
980
    case 1:
357
980
        *lp++ |= (SHS_LONG) 0x80 << 16;
358
980
        break;
359
4.50k
    case 0:
360
4.50k
        *lp++ = (SHS_LONG) 0x80 << 24;
361
6.68k
    }
362
363
    /* at this point, lp can point *past* shsInfo->data.  If it points
364
       there, just Transform and reset.  If it points to the last
365
       element, set that to zero.  This pads out to 64 bytes if not
366
       enough room for length words */
367
368
6.68k
    if (lp == shsInfo->data + 15)
369
307
        *lp++ = 0;
370
371
6.68k
    if (lp == shsInfo->data + 16) {
372
559
        SHSTransform(shsInfo->digest, shsInfo->data);
373
559
        lp = shsInfo->data;
374
559
    }
375
376
    /* Pad out to 56 bytes */
377
61.2k
    while (lp < shsInfo->data + 14)
378
54.5k
        *lp++ = 0;
379
380
    /* Append length in bits and transform */
381
6.68k
    *lp++ = shsInfo->countHi;
382
6.68k
    *lp++ = shsInfo->countLo;
383
6.68k
    SHSTransform(shsInfo->digest, shsInfo->data);
384
6.68k
}
385
386
#endif /* K5_BUILTIN_SHA1 */