diff options
Diffstat (limited to 'lib/sha256.c')
| -rw-r--r-- | lib/sha256.c | 119 |
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 */ |
| 97 | static void | 97 | static void |
| 98 | set_uint32 (char *cp, uint32_t v) | 98 | set_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. */ |
| 105 | void * | 105 | void * |
| 106 | sha256_read_ctx (const struct sha256_ctx *ctx, void *resbuf) | 106 | sha256_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" |
| 175 | int | 175 | |
| 176 | sha256_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. */ | ||
| 180 | static int | ||
| 181 | shaxxx_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 */ | ||
| 246 | int | 256 | int |
| 247 | sha224_stream (FILE *stream, void *resblock) | 257 | sha256_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. */ | 263 | int |
| 311 | sha224_finish_ctx (&ctx, resblock); | 264 | sha224_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. */ |