summaryrefslogtreecommitdiffstats
path: root/gl/sha256.c
diff options
context:
space:
mode:
Diffstat (limited to 'gl/sha256.c')
-rw-r--r--gl/sha256.c433
1 files changed, 433 insertions, 0 deletions
diff --git a/gl/sha256.c b/gl/sha256.c
new file mode 100644
index 00000000..c9ca618c
--- /dev/null
+++ b/gl/sha256.c
@@ -0,0 +1,433 @@
1/* sha256.c - Functions to compute SHA256 and SHA224 message digest of files or
2 memory blocks according to the NIST specification FIPS-180-2.
3
4 Copyright (C) 2005-2006, 2008-2022 Free Software Foundation, Inc.
5
6 This file is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as
8 published by the Free Software Foundation; either version 2.1 of the
9 License, or (at your option) any later version.
10
11 This file is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with this program. If not, see <https://www.gnu.org/licenses/>. */
18
19/* Written by David Madore, considerably copypasting from
20 Scott G. Miller's sha1.c
21*/
22
23#include <config.h>
24
25/* Specification. */
26#if HAVE_OPENSSL_SHA256
27# define GL_OPENSSL_INLINE _GL_EXTERN_INLINE
28#endif
29#include "sha256.h"
30
31#include <stdalign.h>
32#include <stdint.h>
33#include <string.h>
34
35#include <byteswap.h>
36#ifdef WORDS_BIGENDIAN
37# define SWAP(n) (n)
38#else
39# define SWAP(n) bswap_32 (n)
40#endif
41
42#if ! HAVE_OPENSSL_SHA256
43
44/* This array contains the bytes used to pad the buffer to the next
45 64-byte boundary. */
46static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
47
48
49/*
50 Takes a pointer to a 256 bit block of data (eight 32 bit ints) and
51 initializes it to the start constants of the SHA256 algorithm. This
52 must be called before using hash in the call to sha256_hash
53*/
54void
55sha256_init_ctx (struct sha256_ctx *ctx)
56{
57 ctx->state[0] = 0x6a09e667UL;
58 ctx->state[1] = 0xbb67ae85UL;
59 ctx->state[2] = 0x3c6ef372UL;
60 ctx->state[3] = 0xa54ff53aUL;
61 ctx->state[4] = 0x510e527fUL;
62 ctx->state[5] = 0x9b05688cUL;
63 ctx->state[6] = 0x1f83d9abUL;
64 ctx->state[7] = 0x5be0cd19UL;
65
66 ctx->total[0] = ctx->total[1] = 0;
67 ctx->buflen = 0;
68}
69
70void
71sha224_init_ctx (struct sha256_ctx *ctx)
72{
73 ctx->state[0] = 0xc1059ed8UL;
74 ctx->state[1] = 0x367cd507UL;
75 ctx->state[2] = 0x3070dd17UL;
76 ctx->state[3] = 0xf70e5939UL;
77 ctx->state[4] = 0xffc00b31UL;
78 ctx->state[5] = 0x68581511UL;
79 ctx->state[6] = 0x64f98fa7UL;
80 ctx->state[7] = 0xbefa4fa4UL;
81
82 ctx->total[0] = ctx->total[1] = 0;
83 ctx->buflen = 0;
84}
85
86/* Copy the value from v into the memory location pointed to by *CP,
87 If your architecture allows unaligned access, this is equivalent to
88 * (__typeof__ (v) *) cp = v */
89static void
90set_uint32 (char *cp, uint32_t v)
91{
92 memcpy (cp, &v, sizeof v);
93}
94
95/* Put result from CTX in first 32 bytes following RESBUF.
96 The result must be in little endian byte order. */
97void *
98sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf)
99{
100 int i;
101 char *r = resbuf;
102
103 for (i = 0; i < 8; i++)
104 set_uint32 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i]));
105
106 return resbuf;
107}
108
109void *
110sha224_read_ctx (const struct sha256_ctx *ctx, void *resbuf)
111{
112 int i;
113 char *r = resbuf;
114
115 for (i = 0; i < 7; i++)
116 set_uint32 (r + i * sizeof ctx->state[0], SWAP (ctx->state[i]));
117
118 return resbuf;
119}
120
121/* Process the remaining bytes in the internal buffer and the usual
122 prolog according to the standard and write the result to RESBUF. */
123static void
124sha256_conclude_ctx (struct sha256_ctx *ctx)
125{
126 /* Take yet unprocessed bytes into account. */
127 size_t bytes = ctx->buflen;
128 size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4;
129
130 /* Now count remaining bytes. */
131 ctx->total[0] += bytes;
132 if (ctx->total[0] < bytes)
133 ++ctx->total[1];
134
135 /* Put the 64-bit file length in *bits* at the end of the buffer.
136 Use set_uint32 rather than a simple assignment, to avoid risk of
137 unaligned access. */
138 set_uint32 ((char *) &ctx->buffer[size - 2],
139 SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)));
140 set_uint32 ((char *) &ctx->buffer[size - 1],
141 SWAP (ctx->total[0] << 3));
142
143 memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes);
144
145 /* Process last bytes. */
146 sha256_process_block (ctx->buffer, size * 4, ctx);
147}
148
149void *
150sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
151{
152 sha256_conclude_ctx (ctx);
153 return sha256_read_ctx (ctx, resbuf);
154}
155
156void *
157sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
158{
159 sha256_conclude_ctx (ctx);
160 return sha224_read_ctx (ctx, resbuf);
161}
162
163/* Compute SHA256 message digest for LEN bytes beginning at BUFFER. The
164 result is always in little endian byte order, so that a byte-wise
165 output yields to the wanted ASCII representation of the message
166 digest. */
167void *
168sha256_buffer (const char *buffer, size_t len, void *resblock)
169{
170 struct sha256_ctx ctx;
171
172 /* Initialize the computation context. */
173 sha256_init_ctx (&ctx);
174
175 /* Process whole buffer but last len % 64 bytes. */
176 sha256_process_bytes (buffer, len, &ctx);
177
178 /* Put result in desired memory area. */
179 return sha256_finish_ctx (&ctx, resblock);
180}
181
182void *
183sha224_buffer (const char *buffer, size_t len, void *resblock)
184{
185 struct sha256_ctx ctx;
186
187 /* Initialize the computation context. */
188 sha224_init_ctx (&ctx);
189
190 /* Process whole buffer but last len % 64 bytes. */
191 sha256_process_bytes (buffer, len, &ctx);
192
193 /* Put result in desired memory area. */
194 return sha224_finish_ctx (&ctx, resblock);
195}
196
197void
198sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx)
199{
200 /* When we already have some bits in our internal buffer concatenate
201 both inputs first. */
202 if (ctx->buflen != 0)
203 {
204 size_t left_over = ctx->buflen;
205 size_t add = 128 - left_over > len ? len : 128 - left_over;
206
207 memcpy (&((char *) ctx->buffer)[left_over], buffer, add);
208 ctx->buflen += add;
209
210 if (ctx->buflen > 64)
211 {
212 sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
213
214 ctx->buflen &= 63;
215 /* The regions in the following copy operation cannot overlap,
216 because ctx->buflen < 64 ≤ (left_over + add) & ~63. */
217 memcpy (ctx->buffer,
218 &((char *) ctx->buffer)[(left_over + add) & ~63],
219 ctx->buflen);
220 }
221
222 buffer = (const char *) buffer + add;
223 len -= add;
224 }
225
226 /* Process available complete blocks. */
227 if (len >= 64)
228 {
229#if !(_STRING_ARCH_unaligned || _STRING_INLINE_unaligned)
230# define UNALIGNED_P(p) ((uintptr_t) (p) % alignof (uint32_t) != 0)
231 if (UNALIGNED_P (buffer))
232 while (len > 64)
233 {
234 sha256_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
235 buffer = (const char *) buffer + 64;
236 len -= 64;
237 }
238 else
239#endif
240 {
241 sha256_process_block (buffer, len & ~63, ctx);
242 buffer = (const char *) buffer + (len & ~63);
243 len &= 63;
244 }
245 }
246
247 /* Move remaining bytes in internal buffer. */
248 if (len > 0)
249 {
250 size_t left_over = ctx->buflen;
251
252 memcpy (&((char *) ctx->buffer)[left_over], buffer, len);
253 left_over += len;
254 if (left_over >= 64)
255 {
256 sha256_process_block (ctx->buffer, 64, ctx);
257 left_over -= 64;
258 /* The regions in the following copy operation cannot overlap,
259 because left_over ≤ 64. */
260 memcpy (ctx->buffer, &ctx->buffer[16], left_over);
261 }
262 ctx->buflen = left_over;
263 }
264}
265
266/* --- Code below is the primary difference between sha1.c and sha256.c --- */
267
268/* SHA256 round constants */
269#define K(I) sha256_round_constants[I]
270static const uint32_t sha256_round_constants[64] = {
271 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
272 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
273 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
274 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
275 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
276 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
277 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
278 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
279 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
280 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
281 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
282 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
283 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
284 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
285 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
286 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL,
287};
288
289/* Round functions. */
290#define F2(A,B,C) ( ( A & B ) | ( C & ( A | B ) ) )
291#define F1(E,F,G) ( G ^ ( E & ( F ^ G ) ) )
292
293/* Process LEN bytes of BUFFER, accumulating context into CTX.
294 It is assumed that LEN % 64 == 0.
295 Most of this code comes from GnuPG's cipher/sha1.c. */
296
297void
298sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx)
299{
300 const uint32_t *words = buffer;
301 size_t nwords = len / sizeof (uint32_t);
302 const uint32_t *endp = words + nwords;
303 uint32_t x[16];
304 uint32_t a = ctx->state[0];
305 uint32_t b = ctx->state[1];
306 uint32_t c = ctx->state[2];
307 uint32_t d = ctx->state[3];
308 uint32_t e = ctx->state[4];
309 uint32_t f = ctx->state[5];
310 uint32_t g = ctx->state[6];
311 uint32_t h = ctx->state[7];
312 uint32_t lolen = len;
313
314 /* First increment the byte count. FIPS PUB 180-2 specifies the possible
315 length of the file up to 2^64 bits. Here we only compute the
316 number of bytes. Do a double word increment. */
317 ctx->total[0] += lolen;
318 ctx->total[1] += (len >> 31 >> 1) + (ctx->total[0] < lolen);
319
320#define rol(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
321#define S0(x) (rol(x,25)^rol(x,14)^(x>>3))
322#define S1(x) (rol(x,15)^rol(x,13)^(x>>10))
323#define SS0(x) (rol(x,30)^rol(x,19)^rol(x,10))
324#define SS1(x) (rol(x,26)^rol(x,21)^rol(x,7))
325
326#define M(I) ( tm = S1(x[(I-2)&0x0f]) + x[(I-7)&0x0f] \
327 + S0(x[(I-15)&0x0f]) + x[I&0x0f] \
328 , x[I&0x0f] = tm )
329
330#define R(A,B,C,D,E,F,G,H,K,M) do { t0 = SS0(A) + F2(A,B,C); \
331 t1 = H + SS1(E) \
332 + F1(E,F,G) \
333 + K \
334 + M; \
335 D += t1; H = t0 + t1; \
336 } while(0)
337
338 while (words < endp)
339 {
340 uint32_t tm;
341 uint32_t t0, t1;
342 int t;
343 /* FIXME: see sha1.c for a better implementation. */
344 for (t = 0; t < 16; t++)
345 {
346 x[t] = SWAP (*words);
347 words++;
348 }
349
350 R( a, b, c, d, e, f, g, h, K( 0), x[ 0] );
351 R( h, a, b, c, d, e, f, g, K( 1), x[ 1] );
352 R( g, h, a, b, c, d, e, f, K( 2), x[ 2] );
353 R( f, g, h, a, b, c, d, e, K( 3), x[ 3] );
354 R( e, f, g, h, a, b, c, d, K( 4), x[ 4] );
355 R( d, e, f, g, h, a, b, c, K( 5), x[ 5] );
356 R( c, d, e, f, g, h, a, b, K( 6), x[ 6] );
357 R( b, c, d, e, f, g, h, a, K( 7), x[ 7] );
358 R( a, b, c, d, e, f, g, h, K( 8), x[ 8] );
359 R( h, a, b, c, d, e, f, g, K( 9), x[ 9] );
360 R( g, h, a, b, c, d, e, f, K(10), x[10] );
361 R( f, g, h, a, b, c, d, e, K(11), x[11] );
362 R( e, f, g, h, a, b, c, d, K(12), x[12] );
363 R( d, e, f, g, h, a, b, c, K(13), x[13] );
364 R( c, d, e, f, g, h, a, b, K(14), x[14] );
365 R( b, c, d, e, f, g, h, a, K(15), x[15] );
366 R( a, b, c, d, e, f, g, h, K(16), M(16) );
367 R( h, a, b, c, d, e, f, g, K(17), M(17) );
368 R( g, h, a, b, c, d, e, f, K(18), M(18) );
369 R( f, g, h, a, b, c, d, e, K(19), M(19) );
370 R( e, f, g, h, a, b, c, d, K(20), M(20) );
371 R( d, e, f, g, h, a, b, c, K(21), M(21) );
372 R( c, d, e, f, g, h, a, b, K(22), M(22) );
373 R( b, c, d, e, f, g, h, a, K(23), M(23) );
374 R( a, b, c, d, e, f, g, h, K(24), M(24) );
375 R( h, a, b, c, d, e, f, g, K(25), M(25) );
376 R( g, h, a, b, c, d, e, f, K(26), M(26) );
377 R( f, g, h, a, b, c, d, e, K(27), M(27) );
378 R( e, f, g, h, a, b, c, d, K(28), M(28) );
379 R( d, e, f, g, h, a, b, c, K(29), M(29) );
380 R( c, d, e, f, g, h, a, b, K(30), M(30) );
381 R( b, c, d, e, f, g, h, a, K(31), M(31) );
382 R( a, b, c, d, e, f, g, h, K(32), M(32) );
383 R( h, a, b, c, d, e, f, g, K(33), M(33) );
384 R( g, h, a, b, c, d, e, f, K(34), M(34) );
385 R( f, g, h, a, b, c, d, e, K(35), M(35) );
386 R( e, f, g, h, a, b, c, d, K(36), M(36) );
387 R( d, e, f, g, h, a, b, c, K(37), M(37) );
388 R( c, d, e, f, g, h, a, b, K(38), M(38) );
389 R( b, c, d, e, f, g, h, a, K(39), M(39) );
390 R( a, b, c, d, e, f, g, h, K(40), M(40) );
391 R( h, a, b, c, d, e, f, g, K(41), M(41) );
392 R( g, h, a, b, c, d, e, f, K(42), M(42) );
393 R( f, g, h, a, b, c, d, e, K(43), M(43) );
394 R( e, f, g, h, a, b, c, d, K(44), M(44) );
395 R( d, e, f, g, h, a, b, c, K(45), M(45) );
396 R( c, d, e, f, g, h, a, b, K(46), M(46) );
397 R( b, c, d, e, f, g, h, a, K(47), M(47) );
398 R( a, b, c, d, e, f, g, h, K(48), M(48) );
399 R( h, a, b, c, d, e, f, g, K(49), M(49) );
400 R( g, h, a, b, c, d, e, f, K(50), M(50) );
401 R( f, g, h, a, b, c, d, e, K(51), M(51) );
402 R( e, f, g, h, a, b, c, d, K(52), M(52) );
403 R( d, e, f, g, h, a, b, c, K(53), M(53) );
404 R( c, d, e, f, g, h, a, b, K(54), M(54) );
405 R( b, c, d, e, f, g, h, a, K(55), M(55) );
406 R( a, b, c, d, e, f, g, h, K(56), M(56) );
407 R( h, a, b, c, d, e, f, g, K(57), M(57) );
408 R( g, h, a, b, c, d, e, f, K(58), M(58) );
409 R( f, g, h, a, b, c, d, e, K(59), M(59) );
410 R( e, f, g, h, a, b, c, d, K(60), M(60) );
411 R( d, e, f, g, h, a, b, c, K(61), M(61) );
412 R( c, d, e, f, g, h, a, b, K(62), M(62) );
413 R( b, c, d, e, f, g, h, a, K(63), M(63) );
414
415 a = ctx->state[0] += a;
416 b = ctx->state[1] += b;
417 c = ctx->state[2] += c;
418 d = ctx->state[3] += d;
419 e = ctx->state[4] += e;
420 f = ctx->state[5] += f;
421 g = ctx->state[6] += g;
422 h = ctx->state[7] += h;
423 }
424}
425
426#endif
427
428/*
429 * Hey Emacs!
430 * Local Variables:
431 * coding: utf-8
432 * End:
433 */