diff options
Diffstat (limited to 'src/microhttpd/sha256.c')
-rw-r--r-- | src/microhttpd/sha256.c | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/src/microhttpd/sha256.c b/src/microhttpd/sha256.c index 80c41eb5..df6a1aa3 100644 --- a/src/microhttpd/sha256.c +++ b/src/microhttpd/sha256.c | |||
@@ -60,12 +60,6 @@ MHD_SHA256_init (void *ctx_) | |||
60 | 60 | ||
61 | 61 | ||
62 | /** | 62 | /** |
63 | * Number of bytes in single SHA-256 word | ||
64 | * used to process data | ||
65 | */ | ||
66 | #define SHA256_BYTES_IN_WORD 4 | ||
67 | |||
68 | /** | ||
69 | * Base of SHA-256 transformation. | 63 | * Base of SHA-256 transformation. |
70 | * Gets full 64 bytes block of data and updates hash values; | 64 | * Gets full 64 bytes block of data and updates hash values; |
71 | * @param H hash values | 65 | * @param H hash values |
@@ -126,6 +120,18 @@ sha256_transform (uint32_t H[_SHA256_DIGEST_LENGTH], | |||
126 | (vD) += ((vH) += SIG1 ((vE)) + Ch ((vE),(vF),(vG)) + (kt) + (wt)); \ | 120 | (vD) += ((vH) += SIG1 ((vE)) + Ch ((vE),(vF),(vG)) + (kt) + (wt)); \ |
127 | (vH) += SIG0 ((vA)) + Maj ((vA),(vB),(vC)); } while (0) | 121 | (vH) += SIG0 ((vA)) + Maj ((vA),(vB),(vC)); } while (0) |
128 | 122 | ||
123 | #ifndef _MHD_GET_32BIT_BE_UNALIGNED | ||
124 | if (0 != (((uintptr_t) data) % _MHD_UINT32_ALIGN)) | ||
125 | { | ||
126 | /* Copy the unaligned input data to the aligned buffer */ | ||
127 | memcpy (W, data, SHA256_BLOCK_SIZE); | ||
128 | /* The W[] buffer itself will be used as the source of the data, | ||
129 | * but data will be reloaded in correct bytes order during | ||
130 | * the next steps */ | ||
131 | data = (uint8_t*) W; | ||
132 | } | ||
133 | #endif /* _MHD_GET_32BIT_BE_UNALIGNED */ | ||
134 | |||
129 | /* Get value of W(t) from input data buffer, | 135 | /* Get value of W(t) from input data buffer, |
130 | See FIPS PUB 180-4 paragraph 6.2. | 136 | See FIPS PUB 180-4 paragraph 6.2. |
131 | Input data must be read in big-endian bytes order, | 137 | Input data must be read in big-endian bytes order, |
@@ -267,7 +273,7 @@ MHD_SHA256_update (void *ctx_, | |||
267 | return; /* Do nothing */ | 273 | return; /* Do nothing */ |
268 | 274 | ||
269 | /* Note: (count & (SHA256_BLOCK_SIZE-1)) | 275 | /* Note: (count & (SHA256_BLOCK_SIZE-1)) |
270 | equal (count % SHA256_BLOCK_SIZE) for this block size. */ | 276 | equals (count % SHA256_BLOCK_SIZE) for this block size. */ |
271 | bytes_have = (unsigned) (ctx->count & (SHA256_BLOCK_SIZE - 1)); | 277 | bytes_have = (unsigned) (ctx->count & (SHA256_BLOCK_SIZE - 1)); |
272 | ctx->count += length; | 278 | ctx->count += length; |
273 | 279 | ||
@@ -275,7 +281,7 @@ MHD_SHA256_update (void *ctx_, | |||
275 | { | 281 | { |
276 | unsigned bytes_left = SHA256_BLOCK_SIZE - bytes_have; | 282 | unsigned bytes_left = SHA256_BLOCK_SIZE - bytes_have; |
277 | if (length >= bytes_left) | 283 | if (length >= bytes_left) |
278 | { /* Combine new data with data in buffer and | 284 | { /* Combine new data with data in the buffer and |
279 | process full block. */ | 285 | process full block. */ |
280 | memcpy (ctx->buffer + bytes_have, | 286 | memcpy (ctx->buffer + bytes_have, |
281 | data, | 287 | data, |
@@ -289,7 +295,7 @@ MHD_SHA256_update (void *ctx_, | |||
289 | 295 | ||
290 | while (SHA256_BLOCK_SIZE <= length) | 296 | while (SHA256_BLOCK_SIZE <= length) |
291 | { /* Process any full blocks of new data directly, | 297 | { /* Process any full blocks of new data directly, |
292 | without copying to buffer. */ | 298 | without copying to the buffer. */ |
293 | sha256_transform (ctx->H, data); | 299 | sha256_transform (ctx->H, data); |
294 | data += SHA256_BLOCK_SIZE; | 300 | data += SHA256_BLOCK_SIZE; |
295 | length -= SHA256_BLOCK_SIZE; | 301 | length -= SHA256_BLOCK_SIZE; |
@@ -297,7 +303,7 @@ MHD_SHA256_update (void *ctx_, | |||
297 | 303 | ||
298 | if (0 != length) | 304 | if (0 != length) |
299 | { /* Copy incomplete block of new data (if any) | 305 | { /* Copy incomplete block of new data (if any) |
300 | to buffer. */ | 306 | to the buffer. */ |
301 | memcpy (ctx->buffer + bytes_have, data, length); | 307 | memcpy (ctx->buffer + bytes_have, data, length); |
302 | } | 308 | } |
303 | } | 309 | } |
@@ -351,20 +357,42 @@ MHD_SHA256_finish (void *ctx_, | |||
351 | memset (ctx->buffer + bytes_have, 0, | 357 | memset (ctx->buffer + bytes_have, 0, |
352 | SHA256_BLOCK_SIZE - SHA256_SIZE_OF_LEN_ADD - bytes_have); | 358 | SHA256_BLOCK_SIZE - SHA256_SIZE_OF_LEN_ADD - bytes_have); |
353 | /* Put number of bits in processed message as big-endian value. */ | 359 | /* Put number of bits in processed message as big-endian value. */ |
354 | _MHD_PUT_64BIT_BE (ctx->buffer + SHA256_BLOCK_SIZE - SHA256_SIZE_OF_LEN_ADD, | 360 | _MHD_PUT_64BIT_BE_SAFE (ctx->buffer + SHA256_BLOCK_SIZE |
355 | num_bits); | 361 | - SHA256_SIZE_OF_LEN_ADD, |
362 | num_bits); | ||
356 | /* Process full final block. */ | 363 | /* Process full final block. */ |
357 | sha256_transform (ctx->H, ctx->buffer); | 364 | sha256_transform (ctx->H, ctx->buffer); |
358 | 365 | ||
359 | /* Put final hash/digest in BE mode */ | 366 | /* Put final hash/digest in BE mode */ |
360 | _MHD_PUT_32BIT_BE (digest + 0 * SHA256_BYTES_IN_WORD, ctx->H[0]); | 367 | #ifndef _MHD_PUT_32BIT_BE_UNALIGNED |
361 | _MHD_PUT_32BIT_BE (digest + 1 * SHA256_BYTES_IN_WORD, ctx->H[1]); | 368 | if (0 != ((uintptr_t) digest) % _MHD_UINT32_ALIGN) |
362 | _MHD_PUT_32BIT_BE (digest + 2 * SHA256_BYTES_IN_WORD, ctx->H[2]); | 369 | { |
363 | _MHD_PUT_32BIT_BE (digest + 3 * SHA256_BYTES_IN_WORD, ctx->H[3]); | 370 | uint32_t alig_dgst[_SHA256_DIGEST_LENGTH]; |
364 | _MHD_PUT_32BIT_BE (digest + 4 * SHA256_BYTES_IN_WORD, ctx->H[4]); | 371 | _MHD_PUT_32BIT_BE (alig_dgst + 0, ctx->H[0]); |
365 | _MHD_PUT_32BIT_BE (digest + 5 * SHA256_BYTES_IN_WORD, ctx->H[5]); | 372 | _MHD_PUT_32BIT_BE (alig_dgst + 1, ctx->H[1]); |
366 | _MHD_PUT_32BIT_BE (digest + 6 * SHA256_BYTES_IN_WORD, ctx->H[6]); | 373 | _MHD_PUT_32BIT_BE (alig_dgst + 2, ctx->H[2]); |
367 | _MHD_PUT_32BIT_BE (digest + 7 * SHA256_BYTES_IN_WORD, ctx->H[7]); | 374 | _MHD_PUT_32BIT_BE (alig_dgst + 3, ctx->H[3]); |
375 | _MHD_PUT_32BIT_BE (alig_dgst + 4, ctx->H[4]); | ||
376 | _MHD_PUT_32BIT_BE (alig_dgst + 5, ctx->H[5]); | ||
377 | _MHD_PUT_32BIT_BE (alig_dgst + 6, ctx->H[6]); | ||
378 | _MHD_PUT_32BIT_BE (alig_dgst + 7, ctx->H[7]); | ||
379 | /* Copy result to unaligned destination address */ | ||
380 | memcpy (digest, alig_dgst, SHA256_DIGEST_SIZE); | ||
381 | } | ||
382 | else | ||
383 | #else /* _MHD_PUT_32BIT_BE_UNALIGNED */ | ||
384 | if (1) | ||
385 | #endif /* _MHD_PUT_32BIT_BE_UNALIGNED */ | ||
386 | { | ||
387 | _MHD_PUT_32BIT_BE (digest + 0 * SHA256_BYTES_IN_WORD, ctx->H[0]); | ||
388 | _MHD_PUT_32BIT_BE (digest + 1 * SHA256_BYTES_IN_WORD, ctx->H[1]); | ||
389 | _MHD_PUT_32BIT_BE (digest + 2 * SHA256_BYTES_IN_WORD, ctx->H[2]); | ||
390 | _MHD_PUT_32BIT_BE (digest + 3 * SHA256_BYTES_IN_WORD, ctx->H[3]); | ||
391 | _MHD_PUT_32BIT_BE (digest + 4 * SHA256_BYTES_IN_WORD, ctx->H[4]); | ||
392 | _MHD_PUT_32BIT_BE (digest + 5 * SHA256_BYTES_IN_WORD, ctx->H[5]); | ||
393 | _MHD_PUT_32BIT_BE (digest + 6 * SHA256_BYTES_IN_WORD, ctx->H[6]); | ||
394 | _MHD_PUT_32BIT_BE (digest + 7 * SHA256_BYTES_IN_WORD, ctx->H[7]); | ||
395 | } | ||
368 | 396 | ||
369 | /* Erase potentially sensitive data. */ | 397 | /* Erase potentially sensitive data. */ |
370 | memset (ctx, 0, sizeof(struct sha256_ctx)); | 398 | memset (ctx, 0, sizeof(struct sha256_ctx)); |