summaryrefslogtreecommitdiff
path: root/crc
diff options
context:
space:
mode:
authorJens Axboe <axboe@fb.com>2014-09-23 14:08:21 -0600
committerJens Axboe <axboe@fb.com>2014-09-23 14:08:21 -0600
commitf99d67f932abef4b282a394200e90b3180f54802 (patch)
treee777cfcd64a4ef66b6fddf3979f6738c494d6863 /crc
parent5fb55c77dbd78c38d2beb728fb2723e04fec3cd2 (diff)
Checksumming updates
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'crc')
-rw-r--r--crc/md5.c20
-rw-r--r--crc/md5.h1
-rw-r--r--crc/sha256.c64
-rw-r--r--crc/sha256.h8
-rw-r--r--crc/test.c4
5 files changed, 73 insertions, 24 deletions
diff --git a/crc/md5.c b/crc/md5.c
index 0da85e4..64fe48a 100644
--- a/crc/md5.c
+++ b/crc/md5.c
@@ -125,3 +125,23 @@ void fio_md5_update(struct fio_md5_ctx *mctx, const uint8_t *data,
memcpy(mctx->block, data, len);
}
+
+void fio_md5_final(struct fio_md5_ctx *mctx)
+{
+ const unsigned int offset = mctx->byte_count & 0x3f;
+ char *p = (char *)mctx->block + offset;
+ int padding = 56 - (offset + 1);
+
+ *p++ = 0x80;
+ if (padding < 0) {
+ memset(p, 0x00, padding + sizeof (uint64_t));
+ md5_transform(mctx->hash, mctx->block);
+ p = (char *)mctx->block;
+ padding = 56;
+ }
+
+ memset(p, 0, padding);
+ mctx->block[14] = mctx->byte_count << 3;
+ mctx->block[15] = mctx->byte_count >> 29;
+ md5_transform(mctx->hash, mctx->block);
+}
diff --git a/crc/md5.h b/crc/md5.h
index 668f0e9..54e350c 100644
--- a/crc/md5.h
+++ b/crc/md5.h
@@ -23,6 +23,7 @@ struct fio_md5_ctx {
};
extern void fio_md5_update(struct fio_md5_ctx *, const uint8_t *, unsigned int);
+extern void fio_md5_final(struct fio_md5_ctx *);
extern void fio_md5_init(struct fio_md5_ctx *);
#endif
diff --git a/crc/sha256.c b/crc/sha256.c
index 3a72a5b..ae9ff4d 100644
--- a/crc/sha256.c
+++ b/crc/sha256.c
@@ -237,37 +237,57 @@ void fio_sha256_init(struct fio_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 fio_sha256_update(struct fio_sha256_ctx *sctx, const uint8_t *data,
unsigned int len)
{
- unsigned int i, idx, part_len;
+ unsigned int partial, done;
+ const uint8_t *src;
- /* Compute number of bytes mod 128 */
- idx = (unsigned int)((sctx->count[0] >> 3) & 0x3f);
+ partial = sctx->count & 0x3f;
+ sctx->count += len;
+ done = 0;
+ src = data;
- /* Update number of bits */
- if ((sctx->count[0] += (len << 3)) < (len << 3)) {
- sctx->count[1]++;
- sctx->count[1] += (len >> 29);
+ 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);
+}
+
+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, };
- part_len = 64 - idx;
+ /* Save number of bits */
+ bits = sctx->count << 3;
- /* Transform as many times as possible. */
- if (len >= part_len) {
- memcpy(&sctx->buf[idx], data, part_len);
- sha256_transform(sctx->state, sctx->buf);
+ /* 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);
- for (i = part_len; i + 63 < len; i += 64)
- sha256_transform(sctx->state, &data[i]);
- idx = 0;
- } else {
- i = 0;
- }
-
- /* Buffer remaining input */
- memcpy(&sctx->buf[idx], &data[i], len-i);
+ /* Append length (before padding) */
+ fio_sha256_update(sctx, (const uint8_t *)&bits, sizeof(bits));
+
+ /* Store state in digest */
+ for (i = 0; i < 8; i++)
+ sctx->buf[i] = sctx->state[i];
}
diff --git a/crc/sha256.h b/crc/sha256.h
index c7aa28f..b636033 100644
--- a/crc/sha256.h
+++ b/crc/sha256.h
@@ -1,13 +1,17 @@
#ifndef FIO_SHA256_H
#define FIO_SHA256_H
+#define SHA256_DIGEST_SIZE 32
+#define SHA256_BLOCK_SIZE 64
+
struct fio_sha256_ctx {
- uint32_t count[2];
- uint32_t state[8];
+ uint32_t count;
+ uint32_t state[SHA256_DIGEST_SIZE / 4];
uint8_t *buf;
};
void fio_sha256_init(struct fio_sha256_ctx *);
void fio_sha256_update(struct fio_sha256_ctx *, const uint8_t *, unsigned int);
+void fio_sha256_final(struct fio_sha256_ctx *);
#endif
diff --git a/crc/test.c b/crc/test.c
index 0c3b2da..36054e6 100644
--- a/crc/test.c
+++ b/crc/test.c
@@ -52,6 +52,8 @@ static void t_md5(void *buf, size_t size)
for (i = 0; i < NR_CHUNKS; i++)
fio_md5_update(&ctx, buf, size);
+
+ fio_md5_final(&ctx);
}
static void t_crc64(void *buf, size_t size)
@@ -116,6 +118,8 @@ static void t_sha256(void *buf, size_t size)
for (i = 0; i < NR_CHUNKS; i++)
fio_sha256_update(&ctx, buf, size);
+
+ fio_sha256_final(&ctx);
}
static void t_sha512(void *buf, size_t size)