Skip to content

Commit 26052f9

Browse files
committed
crypto: crct10dif - Add fallback for broken initrds
Unfortunately, even with a softdep some distros fail to include the necessary modules in the initrd. Therefore this patch adds a fallback path to restore existing behaviour where we cannot load the new crypto crct10dif algorithm. In order to do this, the underlying crct10dif has been split out from the crypto implementation so that it can be used on the fallback path. Signed-off-by: Herbert Xu <[email protected]>
1 parent 77dbd7a commit 26052f9

File tree

4 files changed

+140
-100
lines changed

4 files changed

+140
-100
lines changed

crypto/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ obj-$(CONFIG_CRYPTO_ZLIB) += zlib.o
8383
obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
8484
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
8585
obj-$(CONFIG_CRYPTO_CRC32) += crc32.o
86-
obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif.o
86+
obj-$(CONFIG_CRYPTO_CRCT10DIF) += crct10dif_common.o crct10dif_generic.o
8787
obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
8888
obj-$(CONFIG_CRYPTO_LZO) += lzo.o
8989
obj-$(CONFIG_CRYPTO_LZ4) += lz4.o

crypto/crct10dif.c renamed to crypto/crct10dif_common.c

Lines changed: 2 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,10 @@
2424
*
2525
*/
2626

27-
#include <linux/types.h>
28-
#include <linux/module.h>
2927
#include <linux/crc-t10dif.h>
30-
#include <crypto/internal/hash.h>
31-
#include <linux/init.h>
32-
#include <linux/string.h>
28+
#include <linux/module.h>
3329
#include <linux/kernel.h>
3430

35-
struct chksum_desc_ctx {
36-
__u16 crc;
37-
};
38-
3931
/* Table generated using the following polynomium:
4032
* x^16 + x^15 + x^11 + x^9 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1
4133
* gt: 0x8bb7
@@ -86,93 +78,5 @@ __u16 crc_t10dif_generic(__u16 crc, const unsigned char *buffer, size_t len)
8678
}
8779
EXPORT_SYMBOL(crc_t10dif_generic);
8880

89-
/*
90-
* Steps through buffer one byte at at time, calculates reflected
91-
* crc using table.
92-
*/
93-
94-
static int chksum_init(struct shash_desc *desc)
95-
{
96-
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
97-
98-
ctx->crc = 0;
99-
100-
return 0;
101-
}
102-
103-
static int chksum_update(struct shash_desc *desc, const u8 *data,
104-
unsigned int length)
105-
{
106-
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
107-
108-
ctx->crc = crc_t10dif_generic(ctx->crc, data, length);
109-
return 0;
110-
}
111-
112-
static int chksum_final(struct shash_desc *desc, u8 *out)
113-
{
114-
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
115-
116-
*(__u16 *)out = ctx->crc;
117-
return 0;
118-
}
119-
120-
static int __chksum_finup(__u16 *crcp, const u8 *data, unsigned int len,
121-
u8 *out)
122-
{
123-
*(__u16 *)out = crc_t10dif_generic(*crcp, data, len);
124-
return 0;
125-
}
126-
127-
static int chksum_finup(struct shash_desc *desc, const u8 *data,
128-
unsigned int len, u8 *out)
129-
{
130-
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
131-
132-
return __chksum_finup(&ctx->crc, data, len, out);
133-
}
134-
135-
static int chksum_digest(struct shash_desc *desc, const u8 *data,
136-
unsigned int length, u8 *out)
137-
{
138-
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
139-
140-
return __chksum_finup(&ctx->crc, data, length, out);
141-
}
142-
143-
static struct shash_alg alg = {
144-
.digestsize = CRC_T10DIF_DIGEST_SIZE,
145-
.init = chksum_init,
146-
.update = chksum_update,
147-
.final = chksum_final,
148-
.finup = chksum_finup,
149-
.digest = chksum_digest,
150-
.descsize = sizeof(struct chksum_desc_ctx),
151-
.base = {
152-
.cra_name = "crct10dif",
153-
.cra_driver_name = "crct10dif-generic",
154-
.cra_priority = 100,
155-
.cra_blocksize = CRC_T10DIF_BLOCK_SIZE,
156-
.cra_module = THIS_MODULE,
157-
}
158-
};
159-
160-
static int __init crct10dif_mod_init(void)
161-
{
162-
int ret;
163-
164-
ret = crypto_register_shash(&alg);
165-
return ret;
166-
}
167-
168-
static void __exit crct10dif_mod_fini(void)
169-
{
170-
crypto_unregister_shash(&alg);
171-
}
172-
173-
module_init(crct10dif_mod_init);
174-
module_exit(crct10dif_mod_fini);
175-
176-
MODULE_AUTHOR("Tim Chen <[email protected]>");
177-
MODULE_DESCRIPTION("T10 DIF CRC calculation.");
81+
MODULE_DESCRIPTION("T10 DIF CRC calculation common code");
17882
MODULE_LICENSE("GPL");

crypto/crct10dif_generic.c

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
/*
2+
* Cryptographic API.
3+
*
4+
* T10 Data Integrity Field CRC16 Crypto Transform
5+
*
6+
* Copyright (c) 2007 Oracle Corporation. All rights reserved.
7+
* Written by Martin K. Petersen <[email protected]>
8+
* Copyright (C) 2013 Intel Corporation
9+
* Author: Tim Chen <[email protected]>
10+
*
11+
* This program is free software; you can redistribute it and/or modify it
12+
* under the terms of the GNU General Public License as published by the Free
13+
* Software Foundation; either version 2 of the License, or (at your option)
14+
* any later version.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20+
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21+
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+
* SOFTWARE.
24+
*
25+
*/
26+
27+
#include <linux/module.h>
28+
#include <linux/crc-t10dif.h>
29+
#include <crypto/internal/hash.h>
30+
#include <linux/init.h>
31+
#include <linux/kernel.h>
32+
33+
struct chksum_desc_ctx {
34+
__u16 crc;
35+
};
36+
37+
/*
38+
* Steps through buffer one byte at at time, calculates reflected
39+
* crc using table.
40+
*/
41+
42+
static int chksum_init(struct shash_desc *desc)
43+
{
44+
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
45+
46+
ctx->crc = 0;
47+
48+
return 0;
49+
}
50+
51+
static int chksum_update(struct shash_desc *desc, const u8 *data,
52+
unsigned int length)
53+
{
54+
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
55+
56+
ctx->crc = crc_t10dif_generic(ctx->crc, data, length);
57+
return 0;
58+
}
59+
60+
static int chksum_final(struct shash_desc *desc, u8 *out)
61+
{
62+
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
63+
64+
*(__u16 *)out = ctx->crc;
65+
return 0;
66+
}
67+
68+
static int __chksum_finup(__u16 *crcp, const u8 *data, unsigned int len,
69+
u8 *out)
70+
{
71+
*(__u16 *)out = crc_t10dif_generic(*crcp, data, len);
72+
return 0;
73+
}
74+
75+
static int chksum_finup(struct shash_desc *desc, const u8 *data,
76+
unsigned int len, u8 *out)
77+
{
78+
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
79+
80+
return __chksum_finup(&ctx->crc, data, len, out);
81+
}
82+
83+
static int chksum_digest(struct shash_desc *desc, const u8 *data,
84+
unsigned int length, u8 *out)
85+
{
86+
struct chksum_desc_ctx *ctx = shash_desc_ctx(desc);
87+
88+
return __chksum_finup(&ctx->crc, data, length, out);
89+
}
90+
91+
static struct shash_alg alg = {
92+
.digestsize = CRC_T10DIF_DIGEST_SIZE,
93+
.init = chksum_init,
94+
.update = chksum_update,
95+
.final = chksum_final,
96+
.finup = chksum_finup,
97+
.digest = chksum_digest,
98+
.descsize = sizeof(struct chksum_desc_ctx),
99+
.base = {
100+
.cra_name = "crct10dif",
101+
.cra_driver_name = "crct10dif-generic",
102+
.cra_priority = 100,
103+
.cra_blocksize = CRC_T10DIF_BLOCK_SIZE,
104+
.cra_module = THIS_MODULE,
105+
}
106+
};
107+
108+
static int __init crct10dif_mod_init(void)
109+
{
110+
int ret;
111+
112+
ret = crypto_register_shash(&alg);
113+
return ret;
114+
}
115+
116+
static void __exit crct10dif_mod_fini(void)
117+
{
118+
crypto_unregister_shash(&alg);
119+
}
120+
121+
module_init(crct10dif_mod_init);
122+
module_exit(crct10dif_mod_fini);
123+
124+
MODULE_AUTHOR("Tim Chen <[email protected]>");
125+
MODULE_DESCRIPTION("T10 DIF CRC calculation.");
126+
MODULE_LICENSE("GPL");
127+
MODULE_ALIAS("crct10dif");

lib/crc-t10dif.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
#include <linux/err.h>
1515
#include <linux/init.h>
1616
#include <crypto/hash.h>
17+
#include <linux/static_key.h>
1718

1819
static struct crypto_shash *crct10dif_tfm;
20+
static struct static_key crct10dif_fallback __read_mostly;
1921

2022
__u16 crc_t10dif(const unsigned char *buffer, size_t len)
2123
{
@@ -25,6 +27,9 @@ __u16 crc_t10dif(const unsigned char *buffer, size_t len)
2527
} desc;
2628
int err;
2729

30+
if (static_key_false(&crct10dif_fallback))
31+
return crc_t10dif_generic(0, buffer, len);
32+
2833
desc.shash.tfm = crct10dif_tfm;
2934
desc.shash.flags = 0;
3035
*(__u16 *)desc.ctx = 0;
@@ -39,7 +44,11 @@ EXPORT_SYMBOL(crc_t10dif);
3944
static int __init crc_t10dif_mod_init(void)
4045
{
4146
crct10dif_tfm = crypto_alloc_shash("crct10dif", 0, 0);
42-
return PTR_RET(crct10dif_tfm);
47+
if (IS_ERR(crct10dif_tfm)) {
48+
static_key_slow_inc(&crct10dif_fallback);
49+
crct10dif_tfm = NULL;
50+
}
51+
return 0;
4352
}
4453

4554
static void __exit crc_t10dif_mod_fini(void)

0 commit comments

Comments
 (0)