]>
Commit | Line | Data |
---|---|---|
448e7440 ZJS |
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
2 | ||
073220bf LP |
3 | /* Stolen from glibc and converted to UEFI style. In glibc it comes with the following copyright blurb: */ |
4 | ||
5 | /* Functions to compute SHA256 message digest of files or memory blocks. | |
6 | according to the definition of SHA256 in FIPS 180-2. | |
7 | Copyright (C) 2007-2019 Free Software Foundation, Inc. | |
8 | This file is part of the GNU C Library. | |
9 | ||
10 | The GNU C Library is free software; you can redistribute it and/or | |
11 | modify it under the terms of the GNU Lesser General Public | |
12 | License as published by the Free Software Foundation; either | |
13 | version 2.1 of the License, or (at your option) any later version. | |
14 | ||
15 | The GNU C Library is distributed in the hope that it will be useful, | |
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
18 | Lesser General Public License for more details. | |
19 | ||
20 | You should have received a copy of the GNU Lesser General Public | |
21 | License along with the GNU C Library; if not, see | |
22 | <http://www.gnu.org/licenses/>. */ | |
23 | ||
24 | /* Written by Ulrich Drepper <drepper@redhat.com>, 2007. */ | |
25 | ||
26 | #include "sha256.h" | |
27 | ||
28 | #if __BYTE_ORDER == __LITTLE_ENDIAN | |
29 | # define SWAP(n) \ | |
30 | (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) | |
31 | # define SWAP64(n) \ | |
32 | (((n) << 56) \ | |
33 | | (((n) & 0xff00) << 40) \ | |
34 | | (((n) & 0xff0000) << 24) \ | |
35 | | (((n) & 0xff000000) << 8) \ | |
36 | | (((n) >> 8) & 0xff000000) \ | |
37 | | (((n) >> 24) & 0xff0000) \ | |
38 | | (((n) >> 40) & 0xff00) \ | |
39 | | ((n) >> 56)) | |
40 | #else | |
41 | # define SWAP(n) (n) | |
42 | # define SWAP64(n) (n) | |
43 | #endif | |
44 | ||
45 | /* This array contains the bytes used to pad the buffer to the next | |
46 | 64-byte boundary. (FIPS 180-2:5.1.1) */ | |
47 | static const UINT8 fillbuf[64] = { | |
48 | 0x80, 0 /* , 0, 0, ... */ | |
49 | }; | |
50 | ||
51 | /* Constants for SHA256 from FIPS 180-2:4.2.2. */ | |
52 | static const UINT32 K[64] = { | |
53 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, | |
54 | 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, | |
55 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, | |
56 | 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, | |
57 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, | |
58 | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, | |
59 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, | |
60 | 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, | |
61 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, | |
62 | 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, | |
63 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, | |
64 | 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, | |
65 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, | |
66 | 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, | |
67 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, | |
68 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 | |
69 | }; | |
70 | ||
71 | static void sha256_process_block(const void *, UINTN, struct sha256_ctx *); | |
72 | ||
73 | /* Initialize structure containing state of computation. | |
74 | (FIPS 180-2:5.3.2) */ | |
75 | void sha256_init_ctx(struct sha256_ctx *ctx) { | |
76 | ctx->H[0] = 0x6a09e667; | |
77 | ctx->H[1] = 0xbb67ae85; | |
78 | ctx->H[2] = 0x3c6ef372; | |
79 | ctx->H[3] = 0xa54ff53a; | |
80 | ctx->H[4] = 0x510e527f; | |
81 | ctx->H[5] = 0x9b05688c; | |
82 | ctx->H[6] = 0x1f83d9ab; | |
83 | ctx->H[7] = 0x5be0cd19; | |
84 | ||
85 | ctx->total64 = 0; | |
86 | ctx->buflen = 0; | |
87 | } | |
88 | ||
89 | /* Process the remaining bytes in the internal buffer and the usual | |
90 | prolog according to the standard and write the result to RESBUF. | |
91 | ||
92 | IMPORTANT: On some systems it is required that RESBUF is correctly | |
93 | aligned for a 32 bits value. */ | |
94 | void *sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf) { | |
95 | /* Take yet unprocessed bytes into account. */ | |
96 | UINT32 bytes = ctx->buflen; | |
97 | UINTN pad, i; | |
98 | ||
99 | /* Now count remaining bytes. */ | |
100 | ctx->total64 += bytes; | |
101 | ||
102 | pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; | |
103 | CopyMem (&ctx->buffer[bytes], fillbuf, pad); | |
104 | ||
105 | /* Put the 64-bit file length in *bits* at the end of the buffer. */ | |
106 | ctx->buffer32[(bytes + pad + 4) / 4] = SWAP (ctx->total[TOTAL64_low] << 3); | |
107 | ctx->buffer32[(bytes + pad) / 4] = SWAP ((ctx->total[TOTAL64_high] << 3) | |
108 | | (ctx->total[TOTAL64_low] >> 29)); | |
109 | ||
110 | /* Process last bytes. */ | |
111 | sha256_process_block (ctx->buffer, bytes + pad + 8, ctx); | |
112 | ||
113 | /* Put result from CTX in first 32 bytes following RESBUF. */ | |
114 | for (i = 0; i < 8; ++i) | |
115 | ((UINT32 *) resbuf)[i] = SWAP (ctx->H[i]); | |
116 | ||
117 | return resbuf; | |
118 | } | |
119 | ||
120 | void sha256_process_bytes(const void *buffer, UINTN len, struct sha256_ctx *ctx) { | |
121 | /* When we already have some bits in our internal buffer concatenate | |
122 | both inputs first. */ | |
123 | ||
124 | if (ctx->buflen != 0) { | |
125 | UINTN left_over = ctx->buflen; | |
126 | UINTN add = 128 - left_over > len ? len : 128 - left_over; | |
127 | ||
128 | CopyMem (&ctx->buffer[left_over], buffer, add); | |
129 | ctx->buflen += add; | |
130 | ||
131 | if (ctx->buflen > 64) { | |
132 | sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx); | |
133 | ||
134 | ctx->buflen &= 63; | |
135 | /* The regions in the following copy operation cannot overlap. */ | |
136 | CopyMem (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], | |
137 | ctx->buflen); | |
138 | } | |
139 | ||
140 | buffer = (const char *) buffer + add; | |
141 | len -= add; | |
142 | } | |
143 | ||
144 | /* Process available complete blocks. */ | |
145 | if (len >= 64) { | |
146 | #if !_STRING_ARCH_unaligned | |
147 | /* To check alignment gcc has an appropriate operator. Other | |
148 | compilers don't. */ | |
149 | # if __GNUC__ >= 2 | |
150 | # define UNALIGNED_P(p) (((UINTN) p) % __alignof__ (UINT32) != 0) | |
151 | # else | |
152 | # define UNALIGNED_P(p) (((UINTN) p) % sizeof (UINT32) != 0) | |
153 | # endif | |
154 | if (UNALIGNED_P (buffer)) | |
155 | while (len > 64) { | |
156 | CopyMem (ctx->buffer, buffer, 64); | |
157 | sha256_process_block (ctx->buffer, 64, ctx); | |
158 | buffer = (const char *) buffer + 64; | |
159 | len -= 64; | |
160 | } | |
161 | else | |
162 | #endif | |
163 | { | |
164 | sha256_process_block (buffer, len & ~63, ctx); | |
165 | buffer = (const char *) buffer + (len & ~63); | |
166 | len &= 63; | |
167 | } | |
168 | } | |
169 | ||
170 | /* Move remaining bytes into internal buffer. */ | |
171 | if (len > 0) { | |
172 | UINTN left_over = ctx->buflen; | |
173 | ||
174 | CopyMem (&ctx->buffer[left_over], buffer, len); | |
175 | left_over += len; | |
176 | if (left_over >= 64) { | |
177 | sha256_process_block (ctx->buffer, 64, ctx); | |
178 | left_over -= 64; | |
179 | CopyMem (ctx->buffer, &ctx->buffer[64], left_over); | |
180 | } | |
181 | ctx->buflen = left_over; | |
182 | } | |
183 | } | |
184 | ||
185 | ||
186 | /* Process LEN bytes of BUFFER, accumulating context into CTX. | |
187 | It is assumed that LEN % 64 == 0. */ | |
188 | static void sha256_process_block(const void *buffer, UINTN len, struct sha256_ctx *ctx) { | |
189 | const UINT32 *words = buffer; | |
190 | UINTN nwords = len / sizeof (UINT32); | |
191 | UINT32 a = ctx->H[0]; | |
192 | UINT32 b = ctx->H[1]; | |
193 | UINT32 c = ctx->H[2]; | |
194 | UINT32 d = ctx->H[3]; | |
195 | UINT32 e = ctx->H[4]; | |
196 | UINT32 f = ctx->H[5]; | |
197 | UINT32 g = ctx->H[6]; | |
198 | UINT32 h = ctx->H[7]; | |
199 | ||
200 | /* First increment the byte count. FIPS 180-2 specifies the possible | |
201 | length of the file up to 2^64 bits. Here we only compute the | |
202 | number of bytes. */ | |
203 | ctx->total64 += len; | |
204 | ||
205 | /* Process all bytes in the buffer with 64 bytes in each round of | |
206 | the loop. */ | |
207 | while (nwords > 0) { | |
208 | UINT32 W[64]; | |
209 | UINT32 a_save = a; | |
210 | UINT32 b_save = b; | |
211 | UINT32 c_save = c; | |
212 | UINT32 d_save = d; | |
213 | UINT32 e_save = e; | |
214 | UINT32 f_save = f; | |
215 | UINT32 g_save = g; | |
216 | UINT32 h_save = h; | |
217 | UINTN t; | |
218 | ||
219 | /* Operators defined in FIPS 180-2:4.1.2. */ | |
220 | #define Ch(x, y, z) ((x & y) ^ (~x & z)) | |
221 | #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) | |
222 | #define S0(x) (CYCLIC (x, 2) ^ CYCLIC (x, 13) ^ CYCLIC (x, 22)) | |
223 | #define S1(x) (CYCLIC (x, 6) ^ CYCLIC (x, 11) ^ CYCLIC (x, 25)) | |
224 | #define R0(x) (CYCLIC (x, 7) ^ CYCLIC (x, 18) ^ (x >> 3)) | |
225 | #define R1(x) (CYCLIC (x, 17) ^ CYCLIC (x, 19) ^ (x >> 10)) | |
226 | ||
227 | /* It is unfortunate that C does not provide an operator for | |
228 | cyclic rotation. Hope the C compiler is smart enough. */ | |
229 | #define CYCLIC(w, s) ((w >> s) | (w << (32 - s))) | |
230 | ||
231 | /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */ | |
232 | for (t = 0; t < 16; ++t) { | |
233 | W[t] = SWAP (*words); | |
234 | ++words; | |
235 | } | |
236 | for (t = 16; t < 64; ++t) | |
237 | W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16]; | |
238 | ||
239 | /* The actual computation according to FIPS 180-2:6.2.2 step 3. */ | |
240 | for (t = 0; t < 64; ++t) { | |
241 | UINT32 T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t]; | |
242 | UINT32 T2 = S0 (a) + Maj (a, b, c); | |
243 | h = g; | |
244 | g = f; | |
245 | f = e; | |
246 | e = d + T1; | |
247 | d = c; | |
248 | c = b; | |
249 | b = a; | |
250 | a = T1 + T2; | |
251 | } | |
252 | ||
253 | /* Add the starting values of the context according to FIPS 180-2:6.2.2 | |
254 | step 4. */ | |
255 | a += a_save; | |
256 | b += b_save; | |
257 | c += c_save; | |
258 | d += d_save; | |
259 | e += e_save; | |
260 | f += f_save; | |
261 | g += g_save; | |
262 | h += h_save; | |
263 | ||
264 | /* Prepare for the next round. */ | |
265 | nwords -= 16; | |
266 | } | |
267 | ||
268 | /* Put checksum in context given as argument. */ | |
269 | ctx->H[0] = a; | |
270 | ctx->H[1] = b; | |
271 | ctx->H[2] = c; | |
272 | ctx->H[3] = d; | |
273 | ctx->H[4] = e; | |
274 | ctx->H[5] = f; | |
275 | ctx->H[6] = g; | |
276 | ctx->H[7] = h; | |
277 | } |