aboutsummaryrefslogtreecommitdiffstats
path: root/lib/sha256.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sha256.c')
-rw-r--r--lib/sha256.c119
1 files changed, 37 insertions, 82 deletions
diff --git a/lib/sha256.c b/lib/sha256.c
index 85405b20fdf..a036befcafd 100644
--- a/lib/sha256.c
+++ b/lib/sha256.c
@@ -91,17 +91,17 @@ sha224_init_ctx (struct sha256_ctx *ctx)
91 ctx->buflen = 0; 91 ctx->buflen = 0;
92} 92}
93 93
94/* Copy the value from v into the memory location pointed to by *cp, 94/* Copy the value from v into the memory location pointed to by *CP,
95 If your architecture allows unaligned access this is equivalent to 95 If your architecture allows unaligned access, this is equivalent to
96 * (uint32_t *) cp = v */ 96 * (__typeof__ (v) *) cp = v */
97static void 97static void
98set_uint32 (char *cp, uint32_t v) 98set_uint32 (char *cp, uint32_t v)
99{ 99{
100 memcpy (cp, &v, sizeof v); 100 memcpy (cp, &v, sizeof v);
101} 101}
102 102
103/* Put result from CTX in first 32 bytes following RESBUF. The result 103/* Put result from CTX in first 32 bytes following RESBUF.
104 must be in little endian byte order. */ 104 The result must be in little endian byte order. */
105void * 105void *
106sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf) 106sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf)
107{ 107{
@@ -169,21 +169,32 @@ sha224_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
169} 169}
170#endif 170#endif
171 171
172/* Compute SHA256 message digest for bytes read from STREAM. The 172#ifdef GL_COMPILE_CRYPTO_STREAM
173 resulting message digest number will be written into the 32 bytes 173
174 beginning at RESBLOCK. */ 174#include "af_alg.h"
175int 175
176sha256_stream (FILE *stream, void *resblock) 176/* Compute message digest for bytes read from STREAM using algorithm ALG.
177 Write the message digest into RESBLOCK, which contains HASHLEN bytes.
178 The initial and finishing operations are INIT_CTX and FINISH_CTX.
179 Return zero if and only if successful. */
180static int
181shaxxx_stream (FILE *stream, char const *alg, void *resblock,
182 ssize_t hashlen, void (*init_ctx) (struct sha256_ctx *),
183 void *(*finish_ctx) (struct sha256_ctx *, void *))
177{ 184{
178 struct sha256_ctx ctx; 185 switch (afalg_stream (stream, alg, resblock, hashlen))
179 size_t sum; 186 {
187 case 0: return 0;
188 case -EIO: return 1;
189 }
180 190
181 char *buffer = malloc (BLOCKSIZE + 72); 191 char *buffer = malloc (BLOCKSIZE + 72);
182 if (!buffer) 192 if (!buffer)
183 return 1; 193 return 1;
184 194
185 /* Initialize the computation context. */ 195 struct sha256_ctx ctx;
186 sha256_init_ctx (&ctx); 196 init_ctx (&ctx);
197 size_t sum;
187 198
188 /* Iterate over full file contents. */ 199 /* Iterate over full file contents. */
189 while (1) 200 while (1)
@@ -237,84 +248,28 @@ sha256_stream (FILE *stream, void *resblock)
237 sha256_process_bytes (buffer, sum, &ctx); 248 sha256_process_bytes (buffer, sum, &ctx);
238 249
239 /* Construct result in desired memory. */ 250 /* Construct result in desired memory. */
240 sha256_finish_ctx (&ctx, resblock); 251 finish_ctx (&ctx, resblock);
241 free (buffer); 252 free (buffer);
242 return 0; 253 return 0;
243} 254}
244 255
245/* FIXME: Avoid code duplication */
246int 256int
247sha224_stream (FILE *stream, void *resblock) 257sha256_stream (FILE *stream, void *resblock)
248{ 258{
249 struct sha256_ctx ctx; 259 return shaxxx_stream (stream, "sha256", resblock, SHA256_DIGEST_SIZE,
250 size_t sum; 260 sha256_init_ctx, sha256_finish_ctx);
251 261}
252 char *buffer = malloc (BLOCKSIZE + 72);
253 if (!buffer)
254 return 1;
255
256 /* Initialize the computation context. */
257 sha224_init_ctx (&ctx);
258
259 /* Iterate over full file contents. */
260 while (1)
261 {
262 /* We read the file in blocks of BLOCKSIZE bytes. One call of the
263 computation function processes the whole buffer so that with the
264 next round of the loop another block can be read. */
265 size_t n;
266 sum = 0;
267
268 /* Read block. Take care for partial reads. */
269 while (1)
270 {
271 n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream);
272
273 sum += n;
274
275 if (sum == BLOCKSIZE)
276 break;
277
278 if (n == 0)
279 {
280 /* Check for the error flag IFF N == 0, so that we don't
281 exit the loop after a partial read due to e.g., EAGAIN
282 or EWOULDBLOCK. */
283 if (ferror (stream))
284 {
285 free (buffer);
286 return 1;
287 }
288 goto process_partial_block;
289 }
290
291 /* We've read at least one byte, so ignore errors. But always
292 check for EOF, since feof may be true even though N > 0.
293 Otherwise, we could end up calling fread after EOF. */
294 if (feof (stream))
295 goto process_partial_block;
296 }
297
298 /* Process buffer with BLOCKSIZE bytes. Note that
299 BLOCKSIZE % 64 == 0
300 */
301 sha256_process_block (buffer, BLOCKSIZE, &ctx);
302 }
303
304 process_partial_block:;
305
306 /* Process any remaining bytes. */
307 if (sum > 0)
308 sha256_process_bytes (buffer, sum, &ctx);
309 262
310 /* Construct result in desired memory. */ 263int
311 sha224_finish_ctx (&ctx, resblock); 264sha224_stream (FILE *stream, void *resblock)
312 free (buffer); 265{
313 return 0; 266 return shaxxx_stream (stream, "sha224", resblock, SHA224_DIGEST_SIZE,
267 sha224_init_ctx, sha224_finish_ctx);
314} 268}
269#endif
315 270
316#if ! HAVE_OPENSSL_SHA256 271#if ! HAVE_OPENSSL_SHA256
317/* Compute SHA512 message digest for LEN bytes beginning at BUFFER. The 272/* Compute SHA256 message digest for LEN bytes beginning at BUFFER. The
318 result is always in little endian byte order, so that a byte-wise 273 result is always in little endian byte order, so that a byte-wise
319 output yields to the wanted ASCII representation of the message 274 output yields to the wanted ASCII representation of the message
320 digest. */ 275 digest. */