@@ -85,6 +85,15 @@ static int chksum_update(struct shash_desc *desc, const u8 *data,
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
}
@@ -98,6 +107,13 @@ static int chksum_final(struct shash_desc *desc, u8 *out)
98
107
}
99
108
100
109
static int __chksum_finup (u32 * crcp , const u8 * data , unsigned int len , u8 * out )
110
+ {
111
+ put_unaligned_le32 (~__crc32c_le_base (* crcp , data , len ), out );
112
+ return 0 ;
113
+ }
114
+
115
+ static int __chksum_finup_arch (u32 * crcp , const u8 * data , unsigned int len ,
116
+ u8 * out )
101
117
{
102
118
put_unaligned_le32 (~__crc32c_le (* crcp , data , len ), out );
103
119
return 0 ;
@@ -111,6 +127,14 @@ static int chksum_finup(struct shash_desc *desc, const u8 *data,
111
127
return __chksum_finup (& ctx -> crc , data , len , out );
112
128
}
113
129
130
+ static int chksum_finup_arch (struct shash_desc * desc , const u8 * data ,
131
+ unsigned int len , u8 * out )
132
+ {
133
+ struct chksum_desc_ctx * ctx = shash_desc_ctx (desc );
134
+
135
+ return __chksum_finup_arch (& ctx -> crc , data , len , out );
136
+ }
137
+
114
138
static int chksum_digest (struct shash_desc * desc , const u8 * data ,
115
139
unsigned int length , u8 * out )
116
140
{
@@ -119,6 +143,14 @@ static int chksum_digest(struct shash_desc *desc, const u8 *data,
119
143
return __chksum_finup (& mctx -> key , data , length , out );
120
144
}
121
145
146
+ static int chksum_digest_arch (struct shash_desc * desc , const u8 * data ,
147
+ unsigned int length , u8 * out )
148
+ {
149
+ struct chksum_ctx * mctx = crypto_shash_ctx (desc -> tfm );
150
+
151
+ return __chksum_finup_arch (& mctx -> key , data , length , out );
152
+ }
153
+
122
154
static int crc32c_cra_init (struct crypto_tfm * tfm )
123
155
{
124
156
struct chksum_ctx * mctx = crypto_tfm_ctx (tfm );
@@ -127,35 +159,53 @@ static int crc32c_cra_init(struct crypto_tfm *tfm)
127
159
return 0 ;
128
160
}
129
161
130
- static struct shash_alg alg = {
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
- .base = {
140
- .cra_name = "crc32c" ,
141
- .cra_driver_name = "crc32c-generic" ,
142
- .cra_priority = 100 ,
143
- .cra_flags = CRYPTO_ALG_OPTIONAL_KEY ,
144
- .cra_blocksize = CHKSUM_BLOCK_SIZE ,
145
- .cra_ctxsize = sizeof (struct chksum_ctx ),
146
- .cra_module = THIS_MODULE ,
147
- .cra_init = crc32c_cra_init ,
148
- }
149
- };
162
+ static struct shash_alg algs [] = {{
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
+
172
+ .base .cra_name = "crc32c" ,
173
+ .base .cra_driver_name = "crc32c-generic" ,
174
+ .base .cra_priority = 100 ,
175
+ .base .cra_flags = CRYPTO_ALG_OPTIONAL_KEY ,
176
+ .base .cra_blocksize = CHKSUM_BLOCK_SIZE ,
177
+ .base .cra_ctxsize = sizeof (struct chksum_ctx ),
178
+ .base .cra_module = THIS_MODULE ,
179
+ .base .cra_init = crc32c_cra_init ,
180
+ }, {
181
+ .digestsize = CHKSUM_DIGEST_SIZE ,
182
+ .setkey = chksum_setkey ,
183
+ .init = chksum_init ,
184
+ .update = chksum_update_arch ,
185
+ .final = chksum_final ,
186
+ .finup = chksum_finup_arch ,
187
+ .digest = chksum_digest_arch ,
188
+ .descsize = sizeof (struct chksum_desc_ctx ),
189
+
190
+ .base .cra_name = "crc32c" ,
191
+ .base .cra_driver_name = "crc32c-" __stringify (ARCH ),
192
+ .base .cra_priority = 150 ,
193
+ .base .cra_flags = CRYPTO_ALG_OPTIONAL_KEY ,
194
+ .base .cra_blocksize = CHKSUM_BLOCK_SIZE ,
195
+ .base .cra_ctxsize = sizeof (struct chksum_ctx ),
196
+ .base .cra_module = THIS_MODULE ,
197
+ .base .cra_init = crc32c_cra_init ,
198
+ }};
150
199
151
200
static int __init crc32c_mod_init (void )
152
201
{
153
- return crypto_register_shash (& alg );
202
+ /* register the arch flavor only if it differs from the generic one */
203
+ return crypto_register_shashes (algs , 1 + (& __crc32c_le != & __crc32c_le_base ));
154
204
}
155
205
156
206
static void __exit crc32c_mod_fini (void )
157
207
{
158
- crypto_unregister_shash ( & alg );
208
+ crypto_unregister_shashes ( algs , 1 + ( & __crc32c_le != & __crc32c_le_base ) );
159
209
}
160
210
161
211
subsys_initcall (crc32c_mod_init );
0 commit comments