diff --git a/crypto/Kconfig b/crypto/Kconfig index 9b347f8..6d65c24 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -36,6 +36,10 @@ config DIGEST_HMAC bool +config DIGEST_CRC32_GENERIC + bool "CRC32" + select CRC32 + config DIGEST_MD5_GENERIC bool "MD5" select MD5 diff --git a/crypto/Makefile b/crypto/Makefile index b4fb3d8..a7240d1 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_CRC16) += crc16.o obj-$(CONFIG_CRC7) += crc7.o obj-$(CONFIG_DIGEST) += digest.o +obj-$(CONFIG_DIGEST_CRC32_GENERIC) += crc32_digest.o obj-$(CONFIG_DIGEST_HMAC_GENERIC) += hmac.o obj-$(CONFIG_DIGEST_MD5_GENERIC) += md5.o obj-$(CONFIG_DIGEST_SHA1_GENERIC) += sha1.o diff --git a/crypto/crc32_digest.c b/crypto/crc32_digest.c new file mode 100644 index 0000000..d322900 --- /dev/null +++ b/crypto/crc32_digest.c @@ -0,0 +1,90 @@ +/* + * Cryptographic API. + * + * CRC32. + * + * Derived from cryptoapi implementation, adapted for in-place + * scatterlist interface. + * + * Copyright (c) Alan Smithee. + * Copyright (c) Andrew McDonald + * Copyright (c) Jean-Francois Dive + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static int crc32_init(struct digest *desc) +{ + struct crc32_state *ctx = digest_ctx(desc); + + ctx->crc = 0; + + return 0; +} + +static int crc32_update(struct digest *desc, const void *data, + unsigned long len) +{ + struct crc32_state *ctx = digest_ctx(desc); + + while (len) { + int now = min((ulong)4096, len); + ctx->crc = crc32(ctx->crc, data, now); + len -= now; + data += now; + } + + return 0; +} + +static int crc32_final(struct digest *desc, unsigned char *md) +{ + struct crc32_state *ctx = digest_ctx(desc); + __be32 *dst = (__be32 *)md; + + /* Store state in digest */ + dst[0] = cpu_to_be32(ctx->crc); + + /* Wipe context */ + memset(ctx, 0, sizeof *ctx); + + return 0; +} + +static struct digest_algo m = { + .base = { + .name = "crc32", + .driver_name = "crc32-generic", + .priority = 0, + .algo = HASH_ALGO_CRC32, + }, + + .init = crc32_init, + .update = crc32_update, + .final = crc32_final, + .digest = digest_generic_digest, + .verify = digest_generic_verify, + .length = CRC32_DIGEST_SIZE, + .ctx_length = sizeof(struct crc32_state), +}; + +static int crc32_digest_register(void) +{ + return digest_algo_register(&m); +} +device_initcall(crc32_digest_register); diff --git a/include/crypto/crc.h b/include/crypto/crc.h new file mode 100644 index 0000000..6428634 --- /dev/null +++ b/include/crypto/crc.h @@ -0,0 +1,16 @@ +/* + * Common values for CRC algorithms + */ + +#ifndef _CRYPTO_CRC_H +#define _CRYPTO_CRC_H + +#include + +#define CRC32_DIGEST_SIZE 4 + +struct crc32_state { + ulong crc; +}; + +#endif diff --git a/include/digest.h b/include/digest.h index fe30cc2..4552e58 100644 --- a/include/digest.h +++ b/include/digest.h @@ -41,6 +41,7 @@ HASH_ALGO_TGR_128, HASH_ALGO_TGR_160, HASH_ALGO_TGR_192, + HASH_ALGO_CRC32, HASH_ALGO__LAST };