/src/nettle/sha256-compress-n.c
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | /* sha256-compress-n.c  | 
2  |  |  | 
3  |  |    The compression function of the sha256 hash function.  | 
4  |  |  | 
5  |  |    Copyright (C) 2001, 2010, 2022 Niels Möller  | 
6  |  |  | 
7  |  |    This file is part of GNU Nettle.  | 
8  |  |  | 
9  |  |    GNU Nettle is free software: you can redistribute it and/or  | 
10  |  |    modify it under the terms of either:  | 
11  |  |  | 
12  |  |      * the GNU Lesser General Public License as published by the Free  | 
13  |  |        Software Foundation; either version 3 of the License, or (at your  | 
14  |  |        option) any later version.  | 
15  |  |  | 
16  |  |    or  | 
17  |  |  | 
18  |  |      * the GNU General Public License as published by the Free  | 
19  |  |        Software Foundation; either version 2 of the License, or (at your  | 
20  |  |        option) any later version.  | 
21  |  |  | 
22  |  |    or both in parallel, as here.  | 
23  |  |  | 
24  |  |    GNU Nettle is distributed in the hope that it will be useful,  | 
25  |  |    but WITHOUT ANY WARRANTY; without even the implied warranty of  | 
26  |  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  | 
27  |  |    General Public License for more details.  | 
28  |  |  | 
29  |  |    You should have received copies of the GNU General Public License and  | 
30  |  |    the GNU Lesser General Public License along with this program.  If  | 
31  |  |    not, see http://www.gnu.org/licenses/.  | 
32  |  | */  | 
33  |  |  | 
34  |  | #if HAVE_CONFIG_H  | 
35  |  | # include "config.h"  | 
36  |  | #endif  | 
37  |  |  | 
38  |  | #ifndef SHA256_DEBUG  | 
39  |  | # define SHA256_DEBUG 0  | 
40  |  | #endif  | 
41  |  |  | 
42  |  | #if SHA256_DEBUG  | 
43  |  | # include <stdio.h>  | 
44  |  | # define DEBUG(i) \  | 
45  |  |   fprintf(stderr, "%2d: %8x %8x %8x %8x %8x %8x %8x %8x\n", \  | 
46  |  |     i, A, B, C, D ,E, F, G, H)  | 
47  |  | #else  | 
48  |  | # define DEBUG(i)  | 
49  |  | #endif  | 
50  |  |  | 
51  |  | #include <assert.h>  | 
52  |  | #include <stdlib.h>  | 
53  |  | #include <string.h>  | 
54  |  |  | 
55  |  | #include "sha2.h"  | 
56  |  | #include "sha2-internal.h"  | 
57  |  |  | 
58  |  | #include "macros.h"  | 
59  |  |  | 
60  |  | /* A block, treated as a sequence of 32-bit words. */  | 
61  | 0  | #define SHA256_DATA_LENGTH 16  | 
62  |  |  | 
63  |  | /* The SHA256 functions. The Choice function is the same as the SHA1  | 
64  |  |    function f1, and the majority function is the same as the SHA1 f3  | 
65  |  |    function. They can be optimized to save one boolean operation each  | 
66  |  |    - thanks to Rich Schroeppel, rcs@cs.arizona.edu for discovering  | 
67  |  |    this */  | 
68  |  |  | 
69  |  | /* #define Choice(x,y,z) ( ( (x) & (y) ) | ( ~(x) & (z) ) ) */  | 
70  | 0  | #define Choice(x,y,z)   ( (z) ^ ( (x) & ( (y) ^ (z) ) ) )   | 
71  |  | /* #define Majority(x,y,z) ( ((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)) ) */  | 
72  | 0  | #define Majority(x,y,z) ( ((x) & (y)) ^ ((z) & ((x) ^ (y))) )  | 
73  |  |  | 
74  | 0  | #define S0(x) (ROTL32(30,(x)) ^ ROTL32(19,(x)) ^ ROTL32(10,(x)))   | 
75  | 0  | #define S1(x) (ROTL32(26,(x)) ^ ROTL32(21,(x)) ^ ROTL32(7,(x)))  | 
76  |  |  | 
77  |  | #define s0(x) (ROTL32(25,(x)) ^ ROTL32(14,(x)) ^ ((x) >> 3))  | 
78  |  | #define s1(x) (ROTL32(15,(x)) ^ ROTL32(13,(x)) ^ ((x) >> 10))  | 
79  |  |  | 
80  |  | /* The initial expanding function.  The hash function is defined over an  | 
81  |  |    64-word expanded input array W, where the first 16 are copies of the input  | 
82  |  |    data, and the remaining 64 are defined by  | 
83  |  |  | 
84  |  |         W[ t ] = s1(W[t-2]) + W[t-7] + s0(W[i-15]) + W[i-16]  | 
85  |  |  | 
86  |  |    This implementation generates these values on the fly in a circular  | 
87  |  |    buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this  | 
88  |  |    optimization.  | 
89  |  | */  | 
90  |  |  | 
91  |  | #define EXPAND(W,i) \  | 
92  |  | ( W[(i) & 15 ] += (s1(W[((i)-2) & 15]) + W[((i)-7) & 15] + s0(W[((i)-15) & 15])) )  | 
93  |  |  | 
94  |  | /* The prototype SHA sub-round.  The fundamental sub-round is:  | 
95  |  |  | 
96  |  |         T1 = h + S1(e) + Choice(e,f,g) + K[t] + W[t]  | 
97  |  |   T2 = S0(a) + Majority(a,b,c)  | 
98  |  |   a' = T1+T2  | 
99  |  |   b' = a  | 
100  |  |   c' = b  | 
101  |  |   d' = c  | 
102  |  |   e' = d + T1  | 
103  |  |   f' = e  | 
104  |  |   g' = f  | 
105  |  |   h' = g  | 
106  |  |  | 
107  |  |    but this is implemented by unrolling the loop 8 times and renaming  | 
108  |  |    the variables  | 
109  |  |    ( h, a, b, c, d, e, f, g ) = ( a, b, c, d, e, f, g, h ) each  | 
110  |  |    iteration. */  | 
111  |  |  | 
112  |  | /* It's crucial that DATA is only used once, as that argument will  | 
113  |  |  * have side effects. */  | 
114  | 0  | #define ROUND(a,b,c,d,e,f,g,h,k,data) do { \ | 
115  | 0  |     h += S1(e) + Choice(e,f,g) + k + data; \  | 
116  | 0  |     d += h;         \  | 
117  | 0  |     h += S0(a) + Majority(a,b,c);    \  | 
118  | 0  |   } while (0)  | 
119  |  |  | 
120  |  | /* For fat builds */  | 
121  |  | #if HAVE_NATIVE_sha256_compress_n  | 
122  |  | const uint8_t *  | 
123  |  | _nettle_sha256_compress_n_c(uint32_t *state, const uint32_t *table,  | 
124  |  |           size_t blocks, const uint8_t *input);  | 
125  |  | #define _nettle_sha256_compress_n _nettle_sha256_compress_n_c  | 
126  |  | #endif  | 
127  |  |  | 
128  |  | const uint8_t *  | 
129  |  | _nettle_sha256_compress_n(uint32_t *state, const uint32_t *table,  | 
130  |  |         size_t blocks, const uint8_t *input)  | 
131  | 0  | { | 
132  | 0  |   uint32_t A, B, C, D, E, F, G, H;     /* Local vars */  | 
133  |  | 
  | 
134  | 0  |   A = state[0];  | 
135  | 0  |   B = state[1];  | 
136  | 0  |   C = state[2];  | 
137  | 0  |   D = state[3];  | 
138  | 0  |   E = state[4];  | 
139  | 0  |   F = state[5];  | 
140  | 0  |   G = state[6];  | 
141  | 0  |   H = state[7];  | 
142  |  | 
  | 
143  | 0  |   for (; blocks > 0; blocks--)  | 
144  | 0  |     { | 
145  | 0  |       uint32_t data[SHA256_DATA_LENGTH];  | 
146  | 0  |       unsigned i;  | 
147  | 0  |       const uint32_t *k;  | 
148  | 0  |       uint32_t *d;  | 
149  | 0  |       for (i = 0; i < SHA256_DATA_LENGTH; i++, input+= 4)  | 
150  | 0  |   { | 
151  | 0  |     data[i] = READ_UINT32(input);  | 
152  | 0  |   }  | 
153  |  |  | 
154  |  |       /* Heavy mangling */  | 
155  |  |       /* First 16 subrounds that act on the original data */  | 
156  |  | 
  | 
157  | 0  |       DEBUG(-1);  | 
158  | 0  |       for (i = 0, d = data, k = table; i<16; i+=8, k += 8, d+= 8)  | 
159  | 0  |   { | 
160  | 0  |     ROUND(A, B, C, D, E, F, G, H, k[0], d[0]); DEBUG(i);  | 
161  | 0  |     ROUND(H, A, B, C, D, E, F, G, k[1], d[1]); DEBUG(i+1);  | 
162  | 0  |     ROUND(G, H, A, B, C, D, E, F, k[2], d[2]);  | 
163  | 0  |     ROUND(F, G, H, A, B, C, D, E, k[3], d[3]);  | 
164  | 0  |     ROUND(E, F, G, H, A, B, C, D, k[4], d[4]);  | 
165  | 0  |     ROUND(D, E, F, G, H, A, B, C, k[5], d[5]);  | 
166  | 0  |     ROUND(C, D, E, F, G, H, A, B, k[6], d[6]); DEBUG(i+6);  | 
167  | 0  |     ROUND(B, C, D, E, F, G, H, A, k[7], d[7]); DEBUG(i+7);  | 
168  | 0  |   }  | 
169  |  |     | 
170  | 0  |       for (; i<64; i += 16, k+= 16)  | 
171  | 0  |   { | 
172  | 0  |     ROUND(A, B, C, D, E, F, G, H, k[ 0], EXPAND(data,  0)); DEBUG(i);  | 
173  | 0  |     ROUND(H, A, B, C, D, E, F, G, k[ 1], EXPAND(data,  1)); DEBUG(i+1);  | 
174  | 0  |     ROUND(G, H, A, B, C, D, E, F, k[ 2], EXPAND(data,  2)); DEBUG(i+2);  | 
175  | 0  |     ROUND(F, G, H, A, B, C, D, E, k[ 3], EXPAND(data,  3)); DEBUG(i+3);  | 
176  | 0  |     ROUND(E, F, G, H, A, B, C, D, k[ 4], EXPAND(data,  4)); DEBUG(i+4);  | 
177  | 0  |     ROUND(D, E, F, G, H, A, B, C, k[ 5], EXPAND(data,  5)); DEBUG(i+5);  | 
178  | 0  |     ROUND(C, D, E, F, G, H, A, B, k[ 6], EXPAND(data,  6)); DEBUG(i+6);  | 
179  | 0  |     ROUND(B, C, D, E, F, G, H, A, k[ 7], EXPAND(data,  7)); DEBUG(i+7);  | 
180  | 0  |     ROUND(A, B, C, D, E, F, G, H, k[ 8], EXPAND(data,  8)); DEBUG(i+8);  | 
181  | 0  |     ROUND(H, A, B, C, D, E, F, G, k[ 9], EXPAND(data,  9)); DEBUG(i+9);  | 
182  | 0  |     ROUND(G, H, A, B, C, D, E, F, k[10], EXPAND(data, 10)); DEBUG(i+10);  | 
183  | 0  |     ROUND(F, G, H, A, B, C, D, E, k[11], EXPAND(data, 11)); DEBUG(i+11);  | 
184  | 0  |     ROUND(E, F, G, H, A, B, C, D, k[12], EXPAND(data, 12)); DEBUG(i+12);  | 
185  | 0  |     ROUND(D, E, F, G, H, A, B, C, k[13], EXPAND(data, 13)); DEBUG(i+13);  | 
186  | 0  |     ROUND(C, D, E, F, G, H, A, B, k[14], EXPAND(data, 14)); DEBUG(i+14);  | 
187  | 0  |     ROUND(B, C, D, E, F, G, H, A, k[15], EXPAND(data, 15)); DEBUG(i+15);  | 
188  | 0  |   }  | 
189  |  |  | 
190  |  |       /* Update state */  | 
191  | 0  |       state[0] = A = state[0] + A;  | 
192  | 0  |       state[1] = B = state[1] + B;  | 
193  | 0  |       state[2] = C = state[2] + C;  | 
194  | 0  |       state[3] = D = state[3] + D;  | 
195  | 0  |       state[4] = E = state[4] + E;  | 
196  | 0  |       state[5] = F = state[5] + F;  | 
197  | 0  |       state[6] = G = state[6] + G;  | 
198  | 0  |       state[7] = H = state[7] + H;  | 
199  |  | #if SHA256_DEBUG  | 
200  |  |       fprintf(stderr, "99: %8x %8x %8x %8x %8x %8x %8x %8x\n",  | 
201  |  |         state[0], state[1], state[2], state[3],  | 
202  |  |         state[4], state[5], state[6], state[7]);  | 
203  |  | #endif  | 
204  | 0  |     }  | 
205  | 0  |   return input;  | 
206  | 0  | }  |