summaryrefslogtreecommitdiffstats
path: root/crypto/cfb.c
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2019-01-03 23:16:16 -0500
committerHerbert Xu <herbert@gondor.apana.org.au>2019-01-11 01:16:57 -0500
commit03b8302ddaad4cf59c0f4f1d60d6a9b4baa3b136 (patch)
tree566f26f132a85e775e22f3b77d100fc4a8b86639 /crypto/cfb.c
parenta5a84a9dbf3d3319c022ff3c9ea76ed3dc332978 (diff)
crypto: cfb - convert to skcipher_alloc_instance_simple()
The CFB template just wraps a single block cipher algorithm, so simplify it by converting it to use skcipher_alloc_instance_simple(). Cc: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: Eric Biggers <ebiggers@google.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'crypto/cfb.c')
-rw-r--r--crypto/cfb.c127
1 files changed, 9 insertions, 118 deletions
diff --git a/crypto/cfb.c b/crypto/cfb.c
index 4abfe32ff845..03ac847f6d6a 100644
--- a/crypto/cfb.c
+++ b/crypto/cfb.c
@@ -25,28 +25,17 @@
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/slab.h>
29#include <linux/string.h> 28#include <linux/string.h>
30#include <linux/types.h>
31
32struct crypto_cfb_ctx {
33 struct crypto_cipher *child;
34};
35 29
36static unsigned int crypto_cfb_bsize(struct crypto_skcipher *tfm) 30static unsigned int crypto_cfb_bsize(struct crypto_skcipher *tfm)
37{ 31{
38 struct crypto_cfb_ctx *ctx = crypto_skcipher_ctx(tfm); 32 return crypto_cipher_blocksize(skcipher_cipher_simple(tfm));
39 struct crypto_cipher *child = ctx->child;
40
41 return crypto_cipher_blocksize(child);
42} 33}
43 34
44static void crypto_cfb_encrypt_one(struct crypto_skcipher *tfm, 35static void crypto_cfb_encrypt_one(struct crypto_skcipher *tfm,
45 const u8 *src, u8 *dst) 36 const u8 *src, u8 *dst)
46{ 37{
47 struct crypto_cfb_ctx *ctx = crypto_skcipher_ctx(tfm); 38 crypto_cipher_encrypt_one(skcipher_cipher_simple(tfm), dst, src);
48
49 crypto_cipher_encrypt_one(ctx->child, dst, src);
50} 39}
51 40
52/* final encrypt and decrypt is the same */ 41/* final encrypt and decrypt is the same */
@@ -186,22 +175,6 @@ static int crypto_cfb_decrypt_blocks(struct skcipher_walk *walk,
186 return crypto_cfb_decrypt_segment(walk, tfm); 175 return crypto_cfb_decrypt_segment(walk, tfm);
187} 176}
188 177
189static int crypto_cfb_setkey(struct crypto_skcipher *parent, const u8 *key,
190 unsigned int keylen)
191{
192 struct crypto_cfb_ctx *ctx = crypto_skcipher_ctx(parent);
193 struct crypto_cipher *child = ctx->child;
194 int err;
195
196 crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
197 crypto_cipher_set_flags(child, crypto_skcipher_get_flags(parent) &
198 CRYPTO_TFM_REQ_MASK);
199 err = crypto_cipher_setkey(child, key, keylen);
200 crypto_skcipher_set_flags(parent, crypto_cipher_get_flags(child) &
201 CRYPTO_TFM_RES_MASK);
202 return err;
203}
204
205static int crypto_cfb_decrypt(struct skcipher_request *req) 178static int crypto_cfb_decrypt(struct skcipher_request *req)
206{ 179{
207 struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); 180 struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
@@ -224,79 +197,18 @@ static int crypto_cfb_decrypt(struct skcipher_request *req)
224 return err; 197 return err;
225} 198}
226 199
227static int crypto_cfb_init_tfm(struct crypto_skcipher *tfm)
228{
229 struct skcipher_instance *inst = skcipher_alg_instance(tfm);
230 struct crypto_spawn *spawn = skcipher_instance_ctx(inst);
231 struct crypto_cfb_ctx *ctx = crypto_skcipher_ctx(tfm);
232 struct crypto_cipher *cipher;
233
234 cipher = crypto_spawn_cipher(spawn);
235 if (IS_ERR(cipher))
236 return PTR_ERR(cipher);
237
238 ctx->child = cipher;
239 return 0;
240}
241
242static void crypto_cfb_exit_tfm(struct crypto_skcipher *tfm)
243{
244 struct crypto_cfb_ctx *ctx = crypto_skcipher_ctx(tfm);
245
246 crypto_free_cipher(ctx->child);
247}
248
249static void crypto_cfb_free(struct skcipher_instance *inst)
250{
251 crypto_drop_skcipher(skcipher_instance_ctx(inst));
252 kfree(inst);
253}
254
255static int crypto_cfb_create(struct crypto_template *tmpl, struct rtattr **tb) 200static int crypto_cfb_create(struct crypto_template *tmpl, struct rtattr **tb)
256{ 201{
257 struct skcipher_instance *inst; 202 struct skcipher_instance *inst;
258 struct crypto_attr_type *algt;
259 struct crypto_spawn *spawn;
260 struct crypto_alg *alg; 203 struct crypto_alg *alg;
261 u32 mask;
262 int err; 204 int err;
263 205
264 err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_SKCIPHER); 206 inst = skcipher_alloc_instance_simple(tmpl, tb, &alg);
265 if (err) 207 if (IS_ERR(inst))
266 return err; 208 return PTR_ERR(inst);
267
268 inst = kzalloc(sizeof(*inst) + sizeof(*spawn), GFP_KERNEL);
269 if (!inst)
270 return -ENOMEM;
271
272 algt = crypto_get_attr_type(tb);
273 err = PTR_ERR(algt);
274 if (IS_ERR(algt))
275 goto err_free_inst;
276 209
277 mask = CRYPTO_ALG_TYPE_MASK | 210 /* CFB mode is a stream cipher. */
278 crypto_requires_off(algt->type, algt->mask,
279 CRYPTO_ALG_NEED_FALLBACK);
280
281 alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER, mask);
282 err = PTR_ERR(alg);
283 if (IS_ERR(alg))
284 goto err_free_inst;
285
286 spawn = skcipher_instance_ctx(inst);
287 err = crypto_init_spawn(spawn, alg, skcipher_crypto_instance(inst),
288 CRYPTO_ALG_TYPE_MASK);
289 if (err)
290 goto err_put_alg;
291
292 err = crypto_inst_setname(skcipher_crypto_instance(inst), "cfb", alg);
293 if (err)
294 goto err_drop_spawn;
295
296 inst->alg.base.cra_priority = alg->cra_priority;
297 /* we're a stream cipher independend of the crypto cra_blocksize */
298 inst->alg.base.cra_blocksize = 1; 211 inst->alg.base.cra_blocksize = 1;
299 inst->alg.base.cra_alignmask = alg->cra_alignmask;
300 212
301 /* 213 /*
302 * To simplify the implementation, configure the skcipher walk to only 214 * To simplify the implementation, configure the skcipher walk to only
@@ -304,36 +216,15 @@ static int crypto_cfb_create(struct crypto_template *tmpl, struct rtattr **tb)
304 */ 216 */
305 inst->alg.chunksize = alg->cra_blocksize; 217 inst->alg.chunksize = alg->cra_blocksize;
306 218
307 inst->alg.ivsize = alg->cra_blocksize;
308 inst->alg.min_keysize = alg->cra_cipher.cia_min_keysize;
309 inst->alg.max_keysize = alg->cra_cipher.cia_max_keysize;
310
311 inst->alg.base.cra_ctxsize = sizeof(struct crypto_cfb_ctx);
312
313 inst->alg.init = crypto_cfb_init_tfm;
314 inst->alg.exit = crypto_cfb_exit_tfm;
315
316 inst->alg.setkey = crypto_cfb_setkey;
317 inst->alg.encrypt = crypto_cfb_encrypt; 219 inst->alg.encrypt = crypto_cfb_encrypt;
318 inst->alg.decrypt = crypto_cfb_decrypt; 220 inst->alg.decrypt = crypto_cfb_decrypt;
319 221
320 inst->free = crypto_cfb_free;
321
322 err = skcipher_register_instance(tmpl, inst); 222 err = skcipher_register_instance(tmpl, inst);
323 if (err) 223 if (err)
324 goto err_drop_spawn; 224 inst->free(inst);
325 crypto_mod_put(alg);
326
327out:
328 return err;
329 225
330err_drop_spawn:
331 crypto_drop_spawn(spawn);
332err_put_alg:
333 crypto_mod_put(alg); 226 crypto_mod_put(alg);
334err_free_inst: 227 return err;
335 kfree(inst);
336 goto out;
337} 228}
338 229
339static struct crypto_template crypto_cfb_tmpl = { 230static struct crypto_template crypto_cfb_tmpl = {
@@ -356,5 +247,5 @@ module_init(crypto_cfb_module_init);
356module_exit(crypto_cfb_module_exit); 247module_exit(crypto_cfb_module_exit);
357 248
358MODULE_LICENSE("GPL"); 249MODULE_LICENSE("GPL");
359MODULE_DESCRIPTION("CFB block cipher algorithm"); 250MODULE_DESCRIPTION("CFB block cipher mode of operation");
360MODULE_ALIAS_CRYPTO("cfb"); 251MODULE_ALIAS_CRYPTO("cfb");