Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: crc32c - Provide crc32c-arch driver for accelerated library code

crc32c-generic is currently backed by the architecture's CRC-32c library
code, which may offer a variety of implementations depending on the
capabilities of the platform. These are not covered by the crypto
subsystem's fuzz testing capabilities because crc32c-generic is the
reference driver that the fuzzing logic uses as a source of truth.

Fix this by providing a crc32c-arch implementation which is based on the
arch library code if available, and modify crc32c-generic so it is
always based on the generic C implementation. If the arch has no CRC-32c
library code, this change does nothing.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Ard Biesheuvel and committed by
Herbert Xu
16739efa a37e5579

+75 -22
+1
crypto/Makefile
··· 155 155 obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o 156 156 obj-$(CONFIG_CRYPTO_CRC32C) += crc32c_generic.o 157 157 obj-$(CONFIG_CRYPTO_CRC32) += crc32_generic.o 158 + CFLAGS_crc32c_generic.o += -DARCH=$(ARCH) 158 159 CFLAGS_crc32_generic.o += -DARCH=$(ARCH) 159 160 obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o 160 161 obj-$(CONFIG_CRYPTO_CRC64_ROCKSOFT) += crc64_rocksoft_generic.o
+72 -22
crypto/crc32c_generic.c
··· 85 85 { 86 86 struct chksum_desc_ctx *ctx = shash_desc_ctx(desc); 87 87 88 + ctx->crc = __crc32c_le_base(ctx->crc, data, length); 89 + return 0; 90 + } 91 + 92 + static int chksum_update_arch(struct shash_desc *desc, const u8 *data, 93 + unsigned int length) 94 + { 95 + struct chksum_desc_ctx *ctx = shash_desc_ctx(desc); 96 + 88 97 ctx->crc = __crc32c_le(ctx->crc, data, length); 89 98 return 0; 90 99 } ··· 108 99 109 100 static int __chksum_finup(u32 *crcp, const u8 *data, unsigned int len, u8 *out) 110 101 { 102 + put_unaligned_le32(~__crc32c_le_base(*crcp, data, len), out); 103 + return 0; 104 + } 105 + 106 + static int __chksum_finup_arch(u32 *crcp, const u8 *data, unsigned int len, 107 + u8 *out) 108 + { 111 109 put_unaligned_le32(~__crc32c_le(*crcp, data, len), out); 112 110 return 0; 113 111 } ··· 127 111 return __chksum_finup(&ctx->crc, data, len, out); 128 112 } 129 113 114 + static int chksum_finup_arch(struct shash_desc *desc, const u8 *data, 115 + unsigned int len, u8 *out) 116 + { 117 + struct chksum_desc_ctx *ctx = shash_desc_ctx(desc); 118 + 119 + return __chksum_finup_arch(&ctx->crc, data, len, out); 120 + } 121 + 130 122 static int chksum_digest(struct shash_desc *desc, const u8 *data, 131 123 unsigned int length, u8 *out) 132 124 { 133 125 struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm); 134 126 135 127 return __chksum_finup(&mctx->key, data, length, out); 128 + } 129 + 130 + static int chksum_digest_arch(struct shash_desc *desc, const u8 *data, 131 + unsigned int length, u8 *out) 132 + { 133 + struct chksum_ctx *mctx = crypto_shash_ctx(desc->tfm); 134 + 135 + return __chksum_finup_arch(&mctx->key, data, length, out); 136 136 } 137 137 138 138 static int crc32c_cra_init(struct crypto_tfm *tfm) ··· 159 127 return 0; 160 128 } 161 129 162 - static struct shash_alg alg = { 163 - .digestsize = CHKSUM_DIGEST_SIZE, 164 - .setkey = chksum_setkey, 165 - .init = chksum_init, 166 - .update = chksum_update, 167 - .final = chksum_final, 168 - .finup = chksum_finup, 169 - .digest = chksum_digest, 170 - .descsize = sizeof(struct chksum_desc_ctx), 171 - .base = { 172 - .cra_name = "crc32c", 173 - .cra_driver_name = "crc32c-generic", 174 - .cra_priority = 100, 175 - .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, 176 - .cra_blocksize = CHKSUM_BLOCK_SIZE, 177 - .cra_ctxsize = sizeof(struct chksum_ctx), 178 - .cra_module = THIS_MODULE, 179 - .cra_init = crc32c_cra_init, 180 - } 181 - }; 130 + static struct shash_alg algs[] = {{ 131 + .digestsize = CHKSUM_DIGEST_SIZE, 132 + .setkey = chksum_setkey, 133 + .init = chksum_init, 134 + .update = chksum_update, 135 + .final = chksum_final, 136 + .finup = chksum_finup, 137 + .digest = chksum_digest, 138 + .descsize = sizeof(struct chksum_desc_ctx), 139 + 140 + .base.cra_name = "crc32c", 141 + .base.cra_driver_name = "crc32c-generic", 142 + .base.cra_priority = 100, 143 + .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY, 144 + .base.cra_blocksize = CHKSUM_BLOCK_SIZE, 145 + .base.cra_ctxsize = sizeof(struct chksum_ctx), 146 + .base.cra_module = THIS_MODULE, 147 + .base.cra_init = crc32c_cra_init, 148 + }, { 149 + .digestsize = CHKSUM_DIGEST_SIZE, 150 + .setkey = chksum_setkey, 151 + .init = chksum_init, 152 + .update = chksum_update_arch, 153 + .final = chksum_final, 154 + .finup = chksum_finup_arch, 155 + .digest = chksum_digest_arch, 156 + .descsize = sizeof(struct chksum_desc_ctx), 157 + 158 + .base.cra_name = "crc32c", 159 + .base.cra_driver_name = "crc32c-" __stringify(ARCH), 160 + .base.cra_priority = 150, 161 + .base.cra_flags = CRYPTO_ALG_OPTIONAL_KEY, 162 + .base.cra_blocksize = CHKSUM_BLOCK_SIZE, 163 + .base.cra_ctxsize = sizeof(struct chksum_ctx), 164 + .base.cra_module = THIS_MODULE, 165 + .base.cra_init = crc32c_cra_init, 166 + }}; 182 167 183 168 static int __init crc32c_mod_init(void) 184 169 { 185 - return crypto_register_shash(&alg); 170 + /* register the arch flavor only if it differs from the generic one */ 171 + return crypto_register_shashes(algs, 1 + (&__crc32c_le != &__crc32c_le_base)); 186 172 } 187 173 188 174 static void __exit crc32c_mod_fini(void) 189 175 { 190 - crypto_unregister_shash(&alg); 176 + crypto_unregister_shashes(algs, 1 + (&__crc32c_le != &__crc32c_le_base)); 191 177 } 192 178 193 179 subsys_initcall(crc32c_mod_init);
+2
lib/crc32.c
··· 208 208 EXPORT_SYMBOL(crc32_le_base); 209 209 210 210 u32 __pure __crc32c_le_base(u32, unsigned char const *, size_t) __alias(__crc32c_le); 211 + EXPORT_SYMBOL(__crc32c_le_base); 212 + 211 213 u32 __pure crc32_be_base(u32, unsigned char const *, size_t) __alias(crc32_be); 212 214 213 215 /*