From 61ddbd35207af8dbd9b1a0c17619148179235203 Mon Sep 17 00:00:00 2001 From: Yegor Yefremov Date: Wed, 25 May 2016 09:51:13 +0200 Subject: crypto: add CRC32 digest CRC32 digest can be used to check CRC32 hashes in FIT images etc. Signed-off-by: Yegor Yefremov Signed-off-by: Sascha Hauer --- crypto/Kconfig | 4 +++ crypto/Makefile | 1 + crypto/crc32_digest.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 crypto/crc32_digest.c (limited to 'crypto') diff --git a/crypto/Kconfig b/crypto/Kconfig index 9b347f872f..6d65c24d4f 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -36,6 +36,10 @@ config SHA512 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 b4fb3d8da0..a7240d1d6e 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_CRC32) += crc32.o 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 0000000000..d322900fcb --- /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); -- cgit v1.2.3