| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
#include <linux/init.h> |
|---|
| 15 |
#include <linux/module.h> |
|---|
| 16 |
#include <linux/string.h> |
|---|
| 17 |
#include <linux/crypto.h> |
|---|
| 18 |
#include <linux/crc32c.h> |
|---|
| 19 |
#include <asm/byteorder.h> |
|---|
| 20 |
|
|---|
| 21 |
#define CHKSUM_BLOCK_SIZE 32 |
|---|
| 22 |
#define CHKSUM_DIGEST_SIZE 4 |
|---|
| 23 |
|
|---|
| 24 |
struct chksum_ctx { |
|---|
| 25 |
u32 crc; |
|---|
| 26 |
}; |
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
|
|---|
| 31 |
|
|---|
| 32 |
|
|---|
| 33 |
static void chksum_init(void *ctx) |
|---|
| 34 |
{ |
|---|
| 35 |
struct chksum_ctx *mctx = ctx; |
|---|
| 36 |
|
|---|
| 37 |
mctx->crc = ~(u32)0; |
|---|
| 38 |
} |
|---|
| 39 |
|
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
static int chksum_setkey(void *ctx, const u8 *key, unsigned int keylen, |
|---|
| 46 |
u32 *flags) |
|---|
| 47 |
{ |
|---|
| 48 |
struct chksum_ctx *mctx = ctx; |
|---|
| 49 |
|
|---|
| 50 |
if (keylen != sizeof(mctx->crc)) { |
|---|
| 51 |
if (flags) |
|---|
| 52 |
*flags = CRYPTO_TFM_RES_BAD_KEY_LEN; |
|---|
| 53 |
return -EINVAL; |
|---|
| 54 |
} |
|---|
| 55 |
mctx->crc = __cpu_to_le32(*(u32 *)key); |
|---|
| 56 |
return 0; |
|---|
| 57 |
} |
|---|
| 58 |
|
|---|
| 59 |
static void chksum_update(void *ctx, const u8 *data, unsigned int length) |
|---|
| 60 |
{ |
|---|
| 61 |
struct chksum_ctx *mctx = ctx; |
|---|
| 62 |
u32 mcrc; |
|---|
| 63 |
|
|---|
| 64 |
mcrc = crc32c(mctx->crc, data, (size_t)length); |
|---|
| 65 |
|
|---|
| 66 |
mctx->crc = mcrc; |
|---|
| 67 |
} |
|---|
| 68 |
|
|---|
| 69 |
static void chksum_final(void *ctx, u8 *out) |
|---|
| 70 |
{ |
|---|
| 71 |
struct chksum_ctx *mctx = ctx; |
|---|
| 72 |
u32 mcrc = (mctx->crc ^ ~(u32)0); |
|---|
| 73 |
|
|---|
| 74 |
*(u32 *)out = __le32_to_cpu(mcrc); |
|---|
| 75 |
} |
|---|
| 76 |
|
|---|
| 77 |
static struct crypto_alg alg = { |
|---|
| 78 |
.cra_name = "crc32c", |
|---|
| 79 |
.cra_flags = CRYPTO_ALG_TYPE_DIGEST, |
|---|
| 80 |
.cra_blocksize = CHKSUM_BLOCK_SIZE, |
|---|
| 81 |
.cra_ctxsize = sizeof(struct chksum_ctx), |
|---|
| 82 |
.cra_module = THIS_MODULE, |
|---|
| 83 |
.cra_list = LIST_HEAD_INIT(alg.cra_list), |
|---|
| 84 |
.cra_u = { |
|---|
| 85 |
.digest = { |
|---|
| 86 |
.dia_digestsize= CHKSUM_DIGEST_SIZE, |
|---|
| 87 |
.dia_setkey = chksum_setkey, |
|---|
| 88 |
.dia_init = chksum_init, |
|---|
| 89 |
.dia_update = chksum_update, |
|---|
| 90 |
.dia_final = chksum_final |
|---|
| 91 |
} |
|---|
| 92 |
} |
|---|
| 93 |
}; |
|---|
| 94 |
|
|---|
| 95 |
static int __init init(void) |
|---|
| 96 |
{ |
|---|
| 97 |
return crypto_register_alg(&alg); |
|---|
| 98 |
} |
|---|
| 99 |
|
|---|
| 100 |
static void __exit fini(void) |
|---|
| 101 |
{ |
|---|
| 102 |
crypto_unregister_alg(&alg); |
|---|
| 103 |
} |
|---|
| 104 |
|
|---|
| 105 |
module_init(init); |
|---|
| 106 |
module_exit(fini); |
|---|
| 107 |
|
|---|
| 108 |
MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>"); |
|---|
| 109 |
MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c"); |
|---|
| 110 |
MODULE_LICENSE("GPL"); |
|---|