Checksumming updates
[fio.git] / crc / sha256.c
index fe08ab3a0e0554ed417e6b7c11dedadffd20677b..ae9ff4d99508190788f6ad33c4d8e5c501fe5676 100644 (file)
 #include <string.h>
 #include <inttypes.h>
 
+#include "../lib/bswap.h"
 #include "sha256.h"
 
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-static int __be32_to_cpu(uint32_t val)
-{
-       uint32_t c1, c2, c3, c4;
-
-       c1 = (val >> 24) & 0xff;
-       c2 = (val >> 16) & 0xff;
-       c3 = (val >> 8) & 0xff;
-       c4 = val & 0xff;
-
-       return c1 | c2 << 8 | c3 << 16 | c4 << 24;
-}
-#else
-#define __be32_to_cpu(x)       (x)
-#endif
-
 #define SHA256_DIGEST_SIZE     32
 #define SHA256_HMAC_BLOCK_SIZE 64
 
@@ -242,7 +227,7 @@ static void sha256_transform(uint32_t *state, const uint8_t *input)
        memset(W, 0, 64 * sizeof(uint32_t));
 }
 
-void sha256_init(struct sha256_ctx *sctx)
+void fio_sha256_init(struct fio_sha256_ctx *sctx)
 {
        sctx->state[0] = H0;
        sctx->state[1] = H1;
@@ -252,37 +237,57 @@ void sha256_init(struct sha256_ctx *sctx)
        sctx->state[5] = H5;
        sctx->state[6] = H6;
        sctx->state[7] = H7;
-       sctx->count[0] = sctx->count[1] = 0;
+       sctx->count = 0;
 }
 
-void sha256_update(struct sha256_ctx *sctx, const uint8_t *data,
-                  unsigned int len)
+void fio_sha256_update(struct fio_sha256_ctx *sctx, const uint8_t *data,
+                      unsigned int len)
 {
-       unsigned int i, index, part_len;
+       unsigned int partial, done;
+       const uint8_t *src;
+
+       partial = sctx->count & 0x3f;
+       sctx->count += len;
+       done = 0;
+       src = data;
+
+       if ((partial + len) > 63) {
+               if (partial) {
+                       done = -partial;
+                       memcpy(sctx->buf + partial, data, done + 64);
+                       src = sctx->buf;
+               }
+
+               do {
+                       sha256_transform(sctx->state, src);
+                       done += 64;
+                       src = data + done;
+               } while (done + 63 < len);
+
+               partial = 0;
+       }
+       memcpy(sctx->buf + partial, src, len - done);
+}
 
-       /* Compute number of bytes mod 128 */
-       index = (unsigned int)((sctx->count[0] >> 3) & 0x3f);
+void fio_sha256_final(struct fio_sha256_ctx *sctx)
+{
+       uint64_t bits;
+       unsigned int index, pad_len;
+       int i;
+       static const uint8_t padding[64] = { 0x80, };
 
-       /* Update number of bits */
-       if ((sctx->count[0] += (len << 3)) < (len << 3)) {
-               sctx->count[1]++;
-               sctx->count[1] += (len >> 29);
-       }
+       /* Save number of bits */
+       bits = sctx->count << 3;
 
-       part_len = 64 - index;
+       /* Pad out to 56 mod 64. */
+       index = sctx->count & 0x3f;
+       pad_len = (index < 56) ? (56 - index) : ((64+56) - index);
+       fio_sha256_update(sctx, padding, pad_len);
 
-       /* Transform as many times as possible. */
-       if (len >= part_len) {
-               memcpy(&sctx->buf[index], data, part_len);
-               sha256_transform(sctx->state, sctx->buf);
+       /* Append length (before padding) */
+       fio_sha256_update(sctx, (const uint8_t *)&bits, sizeof(bits));
 
-               for (i = part_len; i + 63 < len; i += 64)
-                       sha256_transform(sctx->state, &data[i]);
-               index = 0;
-       } else {
-               i = 0;
-       }
-       
-       /* Buffer remaining input */
-       memcpy(&sctx->buf[index], &data[i], len-i);
+       /* Store state in digest */
+       for (i = 0; i < 8; i++)
+               sctx->buf[i] = sctx->state[i];
 }